<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vector>

#include <mesos/mesos.hpp>

#include <process/owned.hpp>
#include <process/gtest.hpp>

#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/gtest.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/uuid.hpp>

#include "slave/paths.hpp"

#ifdef __linux__
#include "slave/containerizer/linux_launcher.hpp"

#include "slave/containerizer/isolators/filesystem/linux.hpp"
#endif

#include "slave/containerizer/mesos/containerizer.hpp"

#include "tests/flags.hpp"
#include "tests/mesos.hpp"

#include "tests/containerizer/provisioner.hpp"
#include "tests/containerizer/rootfs.hpp"

using namespace process;

using std::string;
using std::vector;

using mesos::internal::slave::Fetcher;
using mesos::internal::slave::Launcher;
#ifdef __linux__
using mesos::internal::slave::LinuxFilesystemIsolatorProcess;
using mesos::internal::slave::LinuxLauncher;
#endif
using mesos::internal::slave::MesosContainerizer;
using mesos::internal::slave::Provisioner;
using mesos::internal::slave::Slave;

using mesos::slave::Isolator;

namespace mesos {
namespace internal {
namespace tests {

#ifdef __linux__
class LinuxFilesystemIsolatorTest: public MesosTest
{
public:
  // This helper creates a MesosContainerizer instance that uses the
  // LinuxFilesystemIsolator. The filesystem isolator takes a
  // TestProvisioner which provision APPC images by copying files from
  // the host filesystem.
  Try<Owned<MesosContainerizer>> createContainerizer(const slave::Flags& flags)
  {
    Try<Owned<Rootfs>> rootfs =
      LinuxRootfs::create(path::join(os::getcwd(), "rootfs"));

    if (rootfs.isError()) {
      return Error("Failed to create LinuxRootfs: " + rootfs.error());
    }

    // NOTE: TestProvisioner provisions APPC images.
    hashmap<Image::Type, Owned<Provisioner>> provisioners;
    provisioners.put(
        Image::APPC,
        Owned<Provisioner>(new TestProvisioner(rootfs.get().share())));

    Try<Isolator*> _isolator =
      LinuxFilesystemIsolatorProcess::create(flags, provisioners);

    if (_isolator.isError()) {
      return Error(
          "Failed to create LinuxFilesystemIsolatorProcess: " +
          _isolator.error());
    }

    Owned<Isolator> isolator(_isolator.get());

    Try<Launcher*> _launcher =
      LinuxLauncher::create(flags, isolator->namespaces().get().get());

    if (_launcher.isError()) {
      return Error("Failed to create LinuxLauncher: " + _launcher.error());
    }

    Owned<Launcher> launcher(_launcher.get());

    return Owned<MesosContainerizer>(
        new MesosContainerizer(
            flags,
            true,
            &fetcher,
            launcher,
            {isolator}));
  }

  ContainerInfo createContainerInfo(
      const vector<Volume>& volumes = vector<Volume>(),
      bool hasImage = true)
  {
    ContainerInfo info;
    info.set_type(ContainerInfo::MESOS);

    if (hasImage) {
      info.mutable_mesos()->mutable_image()->set_type(Image::APPC);
    }

    foreach (const Volume& volume, volumes) {
      info.add_volumes()->CopyFrom(volume);
    }

    return info;
  }

private:
  Fetcher fetcher;
};

// This test verifies that the root filesystem of the container is
// properly changed to the one that's provisioned by the provisioner.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystem)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "[ ! -d '" + os::getcwd() + "' ]");

  executor.mutable_container()->CopyFrom(createContainerInfo());

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());
}

// This test verifies that a volume with a relative host path is
// properly created in the container's sandbox and is properly mounted
// in the container's mount namespace.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "echo abc > /tmp/file");

  executor.mutable_container()->CopyFrom(createContainerInfo(
      {CREATE_VOLUME("/tmp", "tmp", Volume::RW)}));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());

  EXPECT_SOME_EQ("abc\n", os::read(path::join(directory, "tmp", "file")));
}

// This test verifies that a volume with an absolute host path as
// well as an absolute container path is properly mounted in the
// container's mount namespace.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "test -d /tmp/sandbox");

  executor.mutable_container()->CopyFrom(createContainerInfo(
      {CREATE_VOLUME("/tmp", os::getcwd(), Volume::RW)}));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());
}

// This test verifies that a volume with an absolute host path and a
// relative container path is properly mounted in the container's
// mount namespace. The mount point will be created in the sandbox.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHostSandboxMountPoint)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "test -d mountpoint/sandbox");

  executor.mutable_container()->CopyFrom(createContainerInfo(
      {CREATE_VOLUME("mountpoint", os::getcwd(), Volume::RW)}));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());
}

// This test verifies that persistent volumes are properly mounted in
// the container's root filesystem.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolume)
{
  slave::Flags flags = CreateSlaveFlags();
  flags.work_dir = os::getcwd();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "echo abc > volume/file");

  executor.add_resources()->CopyFrom(createPersistentVolume(
      Megabytes(32),
      "test_role",
      "persistent_volume_id",
      "volume"));

  executor.mutable_container()->CopyFrom(createContainerInfo());

  // Create a persistent volume.
  string volume = slave::paths::getPersistentVolumePath(
      os::getcwd(),
      "test_role",
      "persistent_volume_id");

  ASSERT_SOME(os::mkdir(volume));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());

  EXPECT_SOME_EQ("abc\n", os::read(path::join(volume, "file")));
}
#endif // __linux__

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<commit_msg>Added a persistent volume test for linux filesystem isolator to test case where the container does not specify a root filesystem.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vector>

#include <mesos/mesos.hpp>

#include <process/owned.hpp>
#include <process/gtest.hpp>

#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/gtest.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/uuid.hpp>

#include "slave/paths.hpp"

#ifdef __linux__
#include "slave/containerizer/linux_launcher.hpp"

#include "slave/containerizer/isolators/filesystem/linux.hpp"
#endif

#include "slave/containerizer/mesos/containerizer.hpp"

#include "tests/flags.hpp"
#include "tests/mesos.hpp"

#include "tests/containerizer/provisioner.hpp"
#include "tests/containerizer/rootfs.hpp"

using namespace process;

using std::string;
using std::vector;

using mesos::internal::slave::Fetcher;
using mesos::internal::slave::Launcher;
#ifdef __linux__
using mesos::internal::slave::LinuxFilesystemIsolatorProcess;
using mesos::internal::slave::LinuxLauncher;
#endif
using mesos::internal::slave::MesosContainerizer;
using mesos::internal::slave::Provisioner;
using mesos::internal::slave::Slave;

using mesos::slave::Isolator;

namespace mesos {
namespace internal {
namespace tests {

#ifdef __linux__
class LinuxFilesystemIsolatorTest: public MesosTest
{
public:
  // This helper creates a MesosContainerizer instance that uses the
  // LinuxFilesystemIsolator. The filesystem isolator takes a
  // TestProvisioner which provision APPC images by copying files from
  // the host filesystem.
  Try<Owned<MesosContainerizer>> createContainerizer(const slave::Flags& flags)
  {
    Try<Owned<Rootfs>> rootfs =
      LinuxRootfs::create(path::join(os::getcwd(), "rootfs"));

    if (rootfs.isError()) {
      return Error("Failed to create LinuxRootfs: " + rootfs.error());
    }

    // NOTE: TestProvisioner provisions APPC images.
    hashmap<Image::Type, Owned<Provisioner>> provisioners;
    provisioners.put(
        Image::APPC,
        Owned<Provisioner>(new TestProvisioner(rootfs.get().share())));

    Try<Isolator*> _isolator =
      LinuxFilesystemIsolatorProcess::create(flags, provisioners);

    if (_isolator.isError()) {
      return Error(
          "Failed to create LinuxFilesystemIsolatorProcess: " +
          _isolator.error());
    }

    Owned<Isolator> isolator(_isolator.get());

    Try<Launcher*> _launcher =
      LinuxLauncher::create(flags, isolator->namespaces().get().get());

    if (_launcher.isError()) {
      return Error("Failed to create LinuxLauncher: " + _launcher.error());
    }

    Owned<Launcher> launcher(_launcher.get());

    return Owned<MesosContainerizer>(
        new MesosContainerizer(
            flags,
            true,
            &fetcher,
            launcher,
            {isolator}));
  }

  ContainerInfo createContainerInfo(
      const vector<Volume>& volumes = vector<Volume>(),
      bool hasImage = true)
  {
    ContainerInfo info;
    info.set_type(ContainerInfo::MESOS);

    if (hasImage) {
      info.mutable_mesos()->mutable_image()->set_type(Image::APPC);
    }

    foreach (const Volume& volume, volumes) {
      info.add_volumes()->CopyFrom(volume);
    }

    return info;
  }

private:
  Fetcher fetcher;
};

// This test verifies that the root filesystem of the container is
// properly changed to the one that's provisioned by the provisioner.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystem)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "[ ! -d '" + os::getcwd() + "' ]");

  executor.mutable_container()->CopyFrom(createContainerInfo());

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());
}

// This test verifies that a volume with a relative host path is
// properly created in the container's sandbox and is properly mounted
// in the container's mount namespace.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "echo abc > /tmp/file");

  executor.mutable_container()->CopyFrom(createContainerInfo(
      {CREATE_VOLUME("/tmp", "tmp", Volume::RW)}));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());

  EXPECT_SOME_EQ("abc\n", os::read(path::join(directory, "tmp", "file")));
}

// This test verifies that a volume with an absolute host path as
// well as an absolute container path is properly mounted in the
// container's mount namespace.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "test -d /tmp/sandbox");

  executor.mutable_container()->CopyFrom(createContainerInfo(
      {CREATE_VOLUME("/tmp", os::getcwd(), Volume::RW)}));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());
}

// This test verifies that a volume with an absolute host path and a
// relative container path is properly mounted in the container's
// mount namespace. The mount point will be created in the sandbox.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHostSandboxMountPoint)
{
  slave::Flags flags = CreateSlaveFlags();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "test -d mountpoint/sandbox");

  executor.mutable_container()->CopyFrom(createContainerInfo(
      {CREATE_VOLUME("mountpoint", os::getcwd(), Volume::RW)}));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());
}

// This test verifies that persistent volumes are properly mounted in
// the container's root filesystem.
TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithRootFilesystem)
{
  slave::Flags flags = CreateSlaveFlags();
  flags.work_dir = os::getcwd();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "echo abc > volume/file");

  executor.add_resources()->CopyFrom(createPersistentVolume(
      Megabytes(32),
      "test_role",
      "persistent_volume_id",
      "volume"));

  executor.mutable_container()->CopyFrom(createContainerInfo());

  // Create a persistent volume.
  string volume = slave::paths::getPersistentVolumePath(
      os::getcwd(),
      "test_role",
      "persistent_volume_id");

  ASSERT_SOME(os::mkdir(volume));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());

  EXPECT_SOME_EQ("abc\n", os::read(path::join(volume, "file")));
}

TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithoutRootFilesystem)
{
  slave::Flags flags = CreateSlaveFlags();
  flags.work_dir = os::getcwd();

  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
  ASSERT_SOME(containerizer);

  ContainerID containerId;
  containerId.set_value(UUID::random().toString());

  ExecutorInfo executor = CREATE_EXECUTOR_INFO(
      "test_executor",
      "echo abc > volume/file");

  executor.add_resources()->CopyFrom(createPersistentVolume(
      Megabytes(32),
      "test_role",
      "persistent_volume_id",
      "volume"));

  executor.mutable_container()->CopyFrom(createContainerInfo({}, false));

  // Create a persistent volume.
  string volume = slave::paths::getPersistentVolumePath(
      os::getcwd(),
      "test_role",
      "persistent_volume_id");

  ASSERT_SOME(os::mkdir(volume));

  string directory = path::join(os::getcwd(), "sandbox");
  ASSERT_SOME(os::mkdir(directory));

  Future<bool> launch = containerizer.get()->launch(
      containerId,
      executor,
      directory,
      None(),
      SlaveID(),
      PID<Slave>(),
      false);

  // Wait for the launch to complete.
  AWAIT_READY(launch);

  // Wait on the container.
  Future<containerizer::Termination> wait =
    containerizer.get()->wait(containerId);

  AWAIT_READY(wait);

  // Check the executor exited correctly.
  EXPECT_TRUE(wait.get().has_status());
  EXPECT_EQ(0, wait.get().status());

  EXPECT_SOME_EQ("abc\n", os::read(path::join(volume, "file")));
}
#endif // __linux__

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/*
** Condor Event Daemon: Take action for planned events in the Condor
** pool, including scheduled reboots.
*/

#include "condor_common.h"
#include "../condor_daemon_core.V6/condor_daemon_core.h"
#include "eventd.h"

const char *mySubSystem = "EVENTD";

int
main_init(int argc, char *argv[])
{
	EventD->Config();
	return TRUE;
}

int
main_config()
{
	EventD->Config();
	return TRUE;
}

int
main_shutdown_fast()
{
	DC_Exit(0);
}

int
main_shutdown_graceful()
{
	DC_Exit(0);
}
<commit_msg>remove const from char *mysubsystem declaration, since condor_daemon_core.h doesn't have the const<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/*
** Condor Event Daemon: Take action for planned events in the Condor
** pool, including scheduled reboots.
*/

#include "condor_common.h"
#include "../condor_daemon_core.V6/condor_daemon_core.h"
#include "eventd.h"

char *mySubSystem = "EVENTD";

int
main_init(int argc, char *argv[])
{
	EventD->Config();
	return TRUE;
}

int
main_config()
{
	EventD->Config();
	return TRUE;
}

int
main_shutdown_fast()
{
	DC_Exit(0);
}

int
main_shutdown_graceful()
{
	DC_Exit(0);
}
<|endoftext|>


<commit_before>// GetParentProcID.cpp : Defines the entry point for the console application.
//

#include "OgrePrerequisites.h"
#include "OgreNsightChecker.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

#include <windows.h>
#include <Psapi.h>
#include <tlhelp32.h>

#pragma comment(lib,"Psapi.lib")

static BOOL WINAPI GetParentPID(PROCESSENTRY32& procentry)
{
	OSVERSIONINFO  osver;
	HINSTANCE      hInstLib;
	HANDLE         hSnapShot;
	BOOL           bContinue;

	// ToolHelp Function Pointers.
	HANDLE(WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD);
	BOOL(WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32);
	BOOL(WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32);

	// Check to see if were running under Windows95 or
	// Windows NT.
	osver.dwOSVersionInfoSize = sizeof(osver);
	if (!GetVersionEx(&osver))
	{
		return FALSE;
	}

	if (osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
	{
		return FALSE;
	}

	hInstLib = LoadLibraryA("Kernel32.DLL");
	if (hInstLib == NULL)
	{
		return FALSE;
	}

	// Get procedure addresses.
	// We are linking to these functions of Kernel32
	// explicitly, because otherwise a module using
	// this code would fail to load under Windows NT,
	// which does not have the Toolhelp32
	// functions in the Kernel 32.
	lpfCreateToolhelp32Snapshot =
		(HANDLE(WINAPI *)(DWORD, DWORD))
		GetProcAddress(hInstLib,
		"CreateToolhelp32Snapshot");
	lpfProcess32First =
		(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32))
		GetProcAddress(hInstLib, "Process32First");
	lpfProcess32Next =
		(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32))
		GetProcAddress(hInstLib, "Process32Next");
	if (lpfProcess32Next == NULL ||
		lpfProcess32First == NULL ||
		lpfCreateToolhelp32Snapshot == NULL)
	{
		FreeLibrary(hInstLib);
		return FALSE;
	}

	// Get a handle to a Toolhelp snapshot of the systems
	// processes.
	hSnapShot = lpfCreateToolhelp32Snapshot(
		TH32CS_SNAPPROCESS, 0);
	if (hSnapShot == INVALID_HANDLE_VALUE)
	{
		FreeLibrary(hInstLib);
		return FALSE;
	}

	// Get the first process' information.
	memset((LPVOID)&procentry, 0, sizeof(PROCESSENTRY32));
	procentry.dwSize = sizeof(PROCESSENTRY32);
	bContinue = lpfProcess32First(hSnapShot, &procentry);
	DWORD pid = 0;
	// While there are processes, keep looping.
	DWORD  crtpid = GetCurrentProcessId();
	while (bContinue)
	{
		if (crtpid == procentry.th32ProcessID)
			pid = procentry.th32ParentProcessID;

		procentry.dwSize = sizeof(PROCESSENTRY32);
		bContinue = !pid && lpfProcess32Next(hSnapShot, &procentry);

	}//while ends

	// Free the library.
	FreeLibrary(hInstLib);

	return pid ? TRUE : FALSE;
}

#ifdef _DEBUG
#define PARENT "msdev.exe"
const DWORD TIMEOUT = 5000;
#else
#define PARENT "idriver.exe"
const DWORD TIMEOUT = 30000;
#endif

static std::string GetProcessFileName(DWORD processID)
{
		std::string result = "";

		HANDLE hProcess = OpenProcess(
			SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
			FALSE, processID);
		if (hProcess != NULL)
		{
			// Here we call EnumProcessModules to get only the
			// first module in the process this is important,
			// because this will be the .EXE module for which we
			// will retrieve the full path name in a second.
			HMODULE        hMod;
			char           szFileName[MAX_PATH];
			DWORD dwSize2 = 0;
			LPTSTR pszName = NULL;
			if (EnumProcessModules(hProcess, &hMod,
				sizeof(hMod), &dwSize2))
			{
				// Get Full pathname:

				if (GetModuleFileNameEx(hProcess, hMod,
					szFileName, sizeof(szFileName)))
					result = std::string(szFileName);
			}
		}

		return result;
}

static bool IsWorkingUnderNsightImpl()
{
	PROCESSENTRY32 selfprocentry;
	if(GetParentPID(selfprocentry))
	{
		std::string parentFileName = GetProcessFileName(selfprocentry.th32ParentProcessID);
		return parentFileName.find("Nsight.Monitor") != std::string::npos;
	}
	return false;
}

#endif

namespace Ogre
{
	bool IsWorkingUnderNsight()
	{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		static bool isWorkingUnderNsight = IsWorkingUnderNsightImpl();
		return isWorkingUnderNsight;
#else
		return false;
#endif
	}
}<commit_msg>Added: support to detect 64 bit versions of NVIDIA Nsight monitor (tweaked)<commit_after>// GetParentProcID.cpp : Defines the entry point for the console application.
//

#include "OgrePrerequisites.h"
#include "OgreNsightChecker.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

#include <windows.h>
#include <Psapi.h>
#include <tlhelp32.h>

#pragma comment(lib,"Psapi.lib")

static BOOL WINAPI GetParentPID(PROCESSENTRY32& procentry)
{
	OSVERSIONINFO  osver;
	HINSTANCE      hInstLib;
	HANDLE         hSnapShot;
	BOOL           bContinue;

	// ToolHelp Function Pointers.
	HANDLE(WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD);
	BOOL(WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32);
	BOOL(WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32);

	// Check to see if were running under Windows95 or
	// Windows NT.
	osver.dwOSVersionInfoSize = sizeof(osver);
	if (!GetVersionEx(&osver))
	{
		return FALSE;
	}

	if (osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
	{
		return FALSE;
	}

	hInstLib = LoadLibraryA("Kernel32.DLL");
	if (hInstLib == NULL)
	{
		return FALSE;
	}

	// Get procedure addresses.
	// We are linking to these functions of Kernel32
	// explicitly, because otherwise a module using
	// this code would fail to load under Windows NT,
	// which does not have the Toolhelp32
	// functions in the Kernel 32.
	lpfCreateToolhelp32Snapshot =
		(HANDLE(WINAPI *)(DWORD, DWORD))
		GetProcAddress(hInstLib,
		"CreateToolhelp32Snapshot");
	lpfProcess32First =
		(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32))
		GetProcAddress(hInstLib, "Process32First");
	lpfProcess32Next =
		(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32))
		GetProcAddress(hInstLib, "Process32Next");
	if (lpfProcess32Next == NULL ||
		lpfProcess32First == NULL ||
		lpfCreateToolhelp32Snapshot == NULL)
	{
		FreeLibrary(hInstLib);
		return FALSE;
	}

	// Get a handle to a Toolhelp snapshot of the systems
	// processes.
	hSnapShot = lpfCreateToolhelp32Snapshot(
		TH32CS_SNAPPROCESS, 0);
	if (hSnapShot == INVALID_HANDLE_VALUE)
	{
		FreeLibrary(hInstLib);
		return FALSE;
	}

	// Get the first process' information.
	memset((LPVOID)&procentry, 0, sizeof(PROCESSENTRY32));
	procentry.dwSize = sizeof(PROCESSENTRY32);
	bContinue = lpfProcess32First(hSnapShot, &procentry);
	DWORD pid = 0;
	// While there are processes, keep looping.
	DWORD  crtpid = GetCurrentProcessId();
	while (bContinue)
	{
		if (crtpid == procentry.th32ProcessID)
			pid = procentry.th32ParentProcessID;

		procentry.dwSize = sizeof(PROCESSENTRY32);
		bContinue = !pid && lpfProcess32Next(hSnapShot, &procentry);

	}//while ends

	// Free the library.
	FreeLibrary(hInstLib);

	return pid ? TRUE : FALSE;
}

static std::string GetProcessFileName(DWORD processID)
{
    char buffer[MAX_PATH] = "";

    HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
    if (hProcess != NULL)
    {
        if(0 == GetProcessImageFileName(hProcess, buffer, ARRAYSIZE(buffer)))
            buffer[0] = 0;

        CloseHandle(hProcess);
    }

    return buffer;
}

static bool IsWorkingUnderNsightImpl()
{
	PROCESSENTRY32 selfprocentry;
	if(GetParentPID(selfprocentry))
	{
		std::string parentFileName = GetProcessFileName(selfprocentry.th32ParentProcessID);
		return parentFileName.find("Nsight.Monitor") != std::string::npos;
	}
	return false;
}

#endif

namespace Ogre
{
	bool IsWorkingUnderNsight()
	{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		static bool isWorkingUnderNsight = IsWorkingUnderNsightImpl();
		return isWorkingUnderNsight;
#else
		return false;
#endif
	}
}<|endoftext|>


<commit_before>#include "MeshManager.hpp"

using namespace Rendering;
using namespace Device;
using namespace Core;
using namespace Rendering::Geometry;
using namespace Rendering::Manager;
using namespace Math;

Mesh& MeshManager::Acquire(Core::ObjectID objID)
{
	auto mesh = Mesh(objID);
	return GetOpaqueMeshPool().Add(mesh);
}

void MeshManager::Delete(Core::ObjectID objID)
{
	GetOpaqueMeshPool().Delete(objID.Literal());
	GetAlphaBlendMeshPool().Delete(objID.Literal());
	GetTransparentMeshPool().Delete(objID.Literal());
}

bool MeshManager::Has(Core::ObjectID objID) const
{
	return	GetOpaqueMeshPool().Has(objID.Literal())		|
			GetAlphaBlendMeshPool().Has(objID.Literal())	|
			GetTransparentMeshPool().Has(objID.Literal());
}

Mesh* MeshManager::Find(Core::ObjectID id)
{
	auto opaque = GetOpaqueMeshPool().Find(id.Literal());
	if (opaque) return opaque;

	auto alpha = GetAlphaBlendMeshPool().Find(id.Literal());
	if (alpha) return alpha;

	auto transparency = GetTransparentMeshPool().Find(id.Literal());
	return transparency;
}

void MeshManager::CheckDirty(const Core::TransformPool& tfPool)
{
	auto& dirty = _dirtyMeshes;
	auto Check = [&dirty, &tfPool](auto& pool)
	{
		pool.Iterate(
			[&dirty, &tfPool](Mesh& mesh)
			{
					auto tf = tfPool.Find(mesh.GetObjectID().Literal()); assert(tf);

					if (tf->GetDirty())
						dirty.push_back(&mesh);
			}
		);
	};

	Check(GetOpaqueMeshPool());
	Check(GetAlphaBlendMeshPool());
	Check(GetTransparentMeshPool());
}

void MeshManager::ComputeWorldSize(
	Vector3& refWorldMin, Vector3& refWorldMax,
	const TransformPool& tfPool) const
{
	auto Compute = [&refWorldMin, &refWorldMax, &tfPool](auto& vector)
	{
		for (auto& iter : vector)
		{
			ObjectID id = iter->GetObjectID();

			const Transform* tf = tfPool.Find(id.Literal()); assert(tf);
			iter->CalcWorldSize(refWorldMin, refWorldMax, *tf);
		}
	};

	Compute(_dirtyMeshes);
}

void MeshManager::UpdateTransformCB(DirectX& dx, const Core::TransformPool& tfPool)
{
	auto Update = [&dx, &tfPool](auto& vector)
	{
		for (auto& mesh : vector)
		{
			uint id = mesh->GetObjectID().Literal();

			const Transform* tf = tfPool.Find(id); assert(tf);
			mesh->UpdateTransformCB(dx, *tf);
		}
	};

	Update(_dirtyMeshes);
}<commit_msg>MeshManager.cpp - Acquire(Core::ObjectID objID) -> Add(Mesh& mesh)<commit_after>#include "MeshManager.hpp"

using namespace Rendering;
using namespace Device;
using namespace Core;
using namespace Rendering::Geometry;
using namespace Rendering::Manager;
using namespace Math;

Mesh& MeshManager::Add(Mesh& mesh)
{
	assert(mesh.GetVBKey() != 0); //Error, mesh does not init yet.
	return GetOpaqueMeshPool().Add(mesh.GetObjectID(), mesh.GetVBKey(), mesh);
}

void MeshManager::Delete(Core::ObjectID objID)
{
	GetOpaqueMeshPool().Delete(objID.Literal());
	GetAlphaBlendMeshPool().Delete(objID.Literal());
	GetTransparentMeshPool().Delete(objID.Literal());
}

bool MeshManager::Has(Core::ObjectID objID) const
{
	return	GetOpaqueMeshPool().Has(objID.Literal())		|
			GetAlphaBlendMeshPool().Has(objID.Literal())	|
			GetTransparentMeshPool().Has(objID.Literal());
}

Mesh* MeshManager::Find(Core::ObjectID id)
{
	auto opaque = GetOpaqueMeshPool().Find(id.Literal());
	if (opaque) return opaque;

	auto alpha = GetAlphaBlendMeshPool().Find(id.Literal());
	if (alpha) return alpha;

	auto transparency = GetTransparentMeshPool().Find(id.Literal());
	return transparency;
}

void MeshManager::CheckDirty(const Core::TransformPool& tfPool)
{
	auto& dirty = _dirtyMeshes;
	auto Check = [&dirty, &tfPool](auto& pool)
	{
		pool.Iterate(
			[&dirty, &tfPool](Mesh& mesh)
			{
					auto tf = tfPool.Find(mesh.GetObjectID().Literal()); assert(tf);

					if (tf->GetDirty())
						dirty.push_back(&mesh);
			}
		);
	};

	Check(GetOpaqueMeshPool());
	Check(GetAlphaBlendMeshPool());
	Check(GetTransparentMeshPool());
}

void MeshManager::ComputeWorldSize(
	Vector3& refWorldMin, Vector3& refWorldMax,
	const TransformPool& tfPool) const
{
	auto Compute = [&refWorldMin, &refWorldMax, &tfPool](auto& vector)
	{
		for (auto& iter : vector)
		{
			ObjectID id = iter->GetObjectID();

			const Transform* tf = tfPool.Find(id.Literal()); assert(tf);
			iter->CalcWorldSize(refWorldMin, refWorldMax, *tf);
		}
	};

	Compute(_dirtyMeshes);
}

void MeshManager::UpdateTransformCB(DirectX& dx, const Core::TransformPool& tfPool)
{
	auto Update = [&dx, &tfPool](auto& vector)
	{
		for (auto& mesh : vector)
		{
			uint id = mesh->GetObjectID().Literal();

			const Transform* tf = tfPool.Find(id); assert(tf);
			mesh->UpdateTransformCB(dx, *tf);
		}
	};

	Update(_dirtyMeshes);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRIBProperty.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkRIBProperty.h"

vtkRIBProperty::vtkRIBProperty ()
{
  this->Declarations = NULL;
  this->Parameters = NULL;
  this->SurfaceShader = NULL;
  this->DisplacementShader = NULL;
}

vtkRIBProperty::~vtkRIBProperty()
{
  if (this->SurfaceShader) delete [] this->SurfaceShader;
  if (this->DisplacementShader) delete [] this->DisplacementShader;
  if (this->Declarations) delete [] this->Declarations;
}

void vtkRIBProperty::SetVariable (char *variable, char *value)
{
  if (this->Declarations) delete [] this->Declarations;

  // format of line is: Declare "variable" "type"\n
  this->Declarations = new char [strlen ("Declare ") +
	                      strlen (variable) +
			      strlen (value) +
			      8];

  sprintf (this->Declarations, "Declare \"%s\" \"%s\"\n", variable, value);
  this->Modified ();
}

void vtkRIBProperty::AddVariable (char *variable, char *value)
{
  if (this->Declarations == NULL)
    {
    this->SetVariable (variable, value);
    }
  else
    {
    char *newVariable = new char [strlen ("Declare ") +
	                          strlen (variable) +
		   	          strlen (value) +
			          8];

    sprintf (newVariable, "Declare \"%s\" \"%s\"\n", variable, value);
    char *oldDeclarations = this->Declarations;

    this->Declarations = new char [strlen (oldDeclarations) + strlen (newVariable) + 1];
    strcpy (this->Declarations, oldDeclarations);
    strcat (this->Declarations, newVariable);
    delete [] oldDeclarations;
    this->Modified ();
    }
}

void vtkRIBProperty::SetParameter (char *parameter, char *value)
{
  if (this->Parameters) delete [] this->Parameters;

  // format of line is: "parameter" "value"
  this->Parameters = new char [strlen (parameter) +
			      strlen (value) +
			      7];

  sprintf (this->Parameters, " \"%s\" [%s]", parameter, value);
  this->Modified ();
}

void vtkRIBProperty::AddParameter (char *Parameter, char *value)
{
  if (this->Parameters == NULL)
    {
    this->SetParameter (Parameter, value);
    }
  else
    {
    char *newParameter = new char [strlen (Parameter) +
		   	          strlen (value) +
			          7];

    sprintf (newParameter, " \"%s\" [%s]", Parameter, value);
    char *oldParameters = this->Parameters;

    this->Parameters = new char [strlen (oldParameters) + strlen (newParameter) + 1];
    strcpy (this->Parameters, oldParameters);
    strcat (this->Parameters, newParameter);
    delete [] oldParameters;
    this->Modified ();
    }
}

char *vtkRIBProperty::GetParameters ()
{
  return this->Parameters;
}

char *vtkRIBProperty::GetDeclarations ()
{
  return this->Declarations;
}

void vtkRIBProperty::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkProperty::PrintSelf(os,indent);

  os << indent << "SurfaceShader: " << this->SurfaceShader << "\n";
  os << indent << "DisplacementShader: " << this->SurfaceShader << "\n";
  os << indent << "Declarations: " << this->Declarations << "\n";
  os << indent << "Parameters: " << this->Parameters << "\n";
}

<commit_msg>ENH: SurfaceShader="plastic" is default.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRIBProperty.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkRIBProperty.h"

vtkRIBProperty::vtkRIBProperty ()
{
  this->Declarations = NULL;
  this->Parameters = NULL;
  this->SurfaceShader = new char[strlen("plastic") + 1];
  strcpy (this->SurfaceShader, "plastic");
  this->DisplacementShader = NULL;
}

vtkRIBProperty::~vtkRIBProperty()
{
  if (this->SurfaceShader) delete [] this->SurfaceShader;
  if (this->DisplacementShader) delete [] this->DisplacementShader;
  if (this->Declarations) delete [] this->Declarations;
}

void vtkRIBProperty::SetVariable (char *variable, char *value)
{
  if (this->Declarations) delete [] this->Declarations;

  // format of line is: Declare "variable" "type"\n
  this->Declarations = new char [strlen ("Declare ") +
	                      strlen (variable) +
			      strlen (value) +
			      8];

  sprintf (this->Declarations, "Declare \"%s\" \"%s\"\n", variable, value);
  this->Modified ();
}

void vtkRIBProperty::AddVariable (char *variable, char *value)
{
  if (this->Declarations == NULL)
    {
    this->SetVariable (variable, value);
    }
  else
    {
    char *newVariable = new char [strlen ("Declare ") +
	                          strlen (variable) +
		   	          strlen (value) +
			          8];

    sprintf (newVariable, "Declare \"%s\" \"%s\"\n", variable, value);
    char *oldDeclarations = this->Declarations;

    this->Declarations = new char [strlen (oldDeclarations) + strlen (newVariable) + 1];
    strcpy (this->Declarations, oldDeclarations);
    strcat (this->Declarations, newVariable);
    delete [] oldDeclarations;
    this->Modified ();
    }
}

void vtkRIBProperty::SetParameter (char *parameter, char *value)
{
  if (this->Parameters) delete [] this->Parameters;

  // format of line is: "parameter" "value"
  this->Parameters = new char [strlen (parameter) +
			      strlen (value) +
			      7];

  sprintf (this->Parameters, " \"%s\" [%s]", parameter, value);
  this->Modified ();
}

void vtkRIBProperty::AddParameter (char *Parameter, char *value)
{
  if (this->Parameters == NULL)
    {
    this->SetParameter (Parameter, value);
    }
  else
    {
    char *newParameter = new char [strlen (Parameter) +
		   	          strlen (value) +
			          7];

    sprintf (newParameter, " \"%s\" [%s]", Parameter, value);
    char *oldParameters = this->Parameters;

    this->Parameters = new char [strlen (oldParameters) + strlen (newParameter) + 1];
    strcpy (this->Parameters, oldParameters);
    strcat (this->Parameters, newParameter);
    delete [] oldParameters;
    this->Modified ();
    }
}

char *vtkRIBProperty::GetParameters ()
{
  return this->Parameters;
}

char *vtkRIBProperty::GetDeclarations ()
{
  return this->Declarations;
}

void vtkRIBProperty::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkProperty::PrintSelf(os,indent);

  os << indent << "SurfaceShader: " << this->SurfaceShader << "\n";
  os << indent << "DisplacementShader: " << this->SurfaceShader << "\n";
  os << indent << "Declarations: " << this->Declarations << "\n";
  os << indent << "Parameters: " << this->Parameters << "\n";
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "core/platform/graphics/GraphicsLayer.h"

#include "core/platform/ScrollableArea.h"
#include "core/platform/graphics/transforms/Matrix3DTransformOperation.h"
#include "core/platform/graphics/transforms/RotateTransformOperation.h"
#include "core/platform/graphics/transforms/TranslateTransformOperation.h"
#include "wtf/PassOwnPtr.h"

#include <gtest/gtest.h>
#include "public/platform/Platform.h"
#include "public/platform/WebCompositorSupport.h"
#include "public/platform/WebFloatAnimationCurve.h"
#include "public/platform/WebGraphicsContext3D.h"
#include "public/platform/WebLayer.h"
#include "public/platform/WebLayerTreeView.h"
#include "public/platform/WebUnitTestSupport.h"

using namespace WebCore;
using namespace WebKit;

namespace {

class MockGraphicsLayerClient : public GraphicsLayerClient {
public:
    virtual void notifyAnimationStarted(const GraphicsLayer*, double time) OVERRIDE { }
    virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip) OVERRIDE { }
};

class GraphicsLayerForTesting : public GraphicsLayer {
public:
    explicit GraphicsLayerForTesting(GraphicsLayerClient* client)
        : GraphicsLayer(client) { };
};

class GraphicsLayerTest : public testing::Test {
public:
    GraphicsLayerTest()
    {
        m_graphicsLayer = adoptPtr(new GraphicsLayerForTesting(&m_client));
        m_platformLayer = m_graphicsLayer->platformLayer();
        m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLayerTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest));
        ASSERT(m_layerTreeView);
        m_layerTreeView->setRootLayer(*m_platformLayer);
        m_layerTreeView->setViewportSize(WebSize(1, 1), WebSize(1, 1));
    }

    virtual ~GraphicsLayerTest()
    {
        m_graphicsLayer.clear();
        m_layerTreeView.clear();
    }

protected:
    WebLayer* m_platformLayer;
    OwnPtr<GraphicsLayerForTesting> m_graphicsLayer;

private:
    OwnPtr<WebLayerTreeView> m_layerTreeView;
    MockGraphicsLayerClient m_client;
};

TEST_F(GraphicsLayerTest, updateLayerPreserves3DWithAnimations)
{
    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());

    OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(Platform::current()->compositorSupport()->createFloatAnimationCurve());
    curve->add(WebFloatKeyframe(0.0, 0.0));
    OwnPtr<WebAnimation> floatAnimation(adoptPtr(Platform::current()->compositorSupport()->createAnimation(*curve, WebAnimation::TargetPropertyOpacity)));
    int animationId = floatAnimation->id();
    ASSERT_TRUE(m_platformLayer->addAnimation(floatAnimation.get()));

    ASSERT_TRUE(m_platformLayer->hasActiveAnimation());

    m_graphicsLayer->setPreserves3D(true);

    m_platformLayer = m_graphicsLayer->platformLayer();
    ASSERT_TRUE(m_platformLayer);

    ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
    m_platformLayer->removeAnimation(animationId);
    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());

    m_graphicsLayer->setPreserves3D(false);

    m_platformLayer = m_graphicsLayer->platformLayer();
    ASSERT_TRUE(m_platformLayer);

    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
}

class FakeScrollableArea : public ScrollableArea {
public:
    virtual bool isActive() const OVERRIDE { return false; }
    virtual int scrollSize(ScrollbarOrientation) const OVERRIDE { return 100; }
    virtual int scrollPosition(Scrollbar*) const OVERRIDE { return 0; }
    virtual bool isScrollCornerVisible() const OVERRIDE { return false; }
    virtual IntRect scrollCornerRect() const OVERRIDE { return IntRect(); }
    virtual int visibleWidth() const OVERRIDE { return 10; }
    virtual int visibleHeight() const OVERRIDE { return 10; }
    virtual IntSize contentsSize() const OVERRIDE { return IntSize(100, 100); }
    virtual bool scrollbarsCanBeActive() const OVERRIDE { return false; }
    virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE { return 0; }
    virtual IntRect scrollableAreaBoundingBox() const OVERRIDE { return IntRect(); }
    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE { }
    virtual void invalidateScrollCornerRect(const IntRect&) OVERRIDE { }

    virtual void setScrollOffset(const IntPoint& scrollOffset) OVERRIDE { m_scrollPosition = scrollOffset; }
    virtual IntPoint scrollPosition() const OVERRIDE { return m_scrollPosition; }

private:
    IntPoint m_scrollPosition;
};

TEST_F(GraphicsLayerTest, applyScrollToScrollableArea)
{
    FakeScrollableArea scrollableArea;
    m_graphicsLayer->setScrollableArea(&scrollableArea);

    WebPoint scrollPosition(7, 9);
    m_platformLayer->setScrollPosition(scrollPosition);

    EXPECT_EQ(scrollPosition, WebPoint(scrollableArea.scrollPosition()));
}

TEST_F(GraphicsLayerTest, DISABLED_setContentsToSolidColor)
{
    m_graphicsLayer->setContentsToSolidColor(Color::transparent);
    EXPECT_FALSE(m_graphicsLayer->contentsLayer());

    m_graphicsLayer->setContentsToSolidColor(Color::white);
    EXPECT_TRUE(m_graphicsLayer->contentsLayer());

    m_graphicsLayer->setContentsToSolidColor(Color());
    EXPECT_FALSE(m_graphicsLayer->contentsLayer());
}

} // namespace
<commit_msg>Disable GraphicsLayerTest.applyScrollToScrollableArea which broke after r204442<commit_after>/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "core/platform/graphics/GraphicsLayer.h"

#include "core/platform/ScrollableArea.h"
#include "core/platform/graphics/transforms/Matrix3DTransformOperation.h"
#include "core/platform/graphics/transforms/RotateTransformOperation.h"
#include "core/platform/graphics/transforms/TranslateTransformOperation.h"
#include "wtf/PassOwnPtr.h"

#include <gtest/gtest.h>
#include "public/platform/Platform.h"
#include "public/platform/WebCompositorSupport.h"
#include "public/platform/WebFloatAnimationCurve.h"
#include "public/platform/WebGraphicsContext3D.h"
#include "public/platform/WebLayer.h"
#include "public/platform/WebLayerTreeView.h"
#include "public/platform/WebUnitTestSupport.h"

using namespace WebCore;
using namespace WebKit;

namespace {

class MockGraphicsLayerClient : public GraphicsLayerClient {
public:
    virtual void notifyAnimationStarted(const GraphicsLayer*, double time) OVERRIDE { }
    virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip) OVERRIDE { }
};

class GraphicsLayerForTesting : public GraphicsLayer {
public:
    explicit GraphicsLayerForTesting(GraphicsLayerClient* client)
        : GraphicsLayer(client) { };
};

class GraphicsLayerTest : public testing::Test {
public:
    GraphicsLayerTest()
    {
        m_graphicsLayer = adoptPtr(new GraphicsLayerForTesting(&m_client));
        m_platformLayer = m_graphicsLayer->platformLayer();
        m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLayerTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest));
        ASSERT(m_layerTreeView);
        m_layerTreeView->setRootLayer(*m_platformLayer);
        m_layerTreeView->setViewportSize(WebSize(1, 1), WebSize(1, 1));
    }

    virtual ~GraphicsLayerTest()
    {
        m_graphicsLayer.clear();
        m_layerTreeView.clear();
    }

protected:
    WebLayer* m_platformLayer;
    OwnPtr<GraphicsLayerForTesting> m_graphicsLayer;

private:
    OwnPtr<WebLayerTreeView> m_layerTreeView;
    MockGraphicsLayerClient m_client;
};

TEST_F(GraphicsLayerTest, updateLayerPreserves3DWithAnimations)
{
    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());

    OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(Platform::current()->compositorSupport()->createFloatAnimationCurve());
    curve->add(WebFloatKeyframe(0.0, 0.0));
    OwnPtr<WebAnimation> floatAnimation(adoptPtr(Platform::current()->compositorSupport()->createAnimation(*curve, WebAnimation::TargetPropertyOpacity)));
    int animationId = floatAnimation->id();
    ASSERT_TRUE(m_platformLayer->addAnimation(floatAnimation.get()));

    ASSERT_TRUE(m_platformLayer->hasActiveAnimation());

    m_graphicsLayer->setPreserves3D(true);

    m_platformLayer = m_graphicsLayer->platformLayer();
    ASSERT_TRUE(m_platformLayer);

    ASSERT_TRUE(m_platformLayer->hasActiveAnimation());
    m_platformLayer->removeAnimation(animationId);
    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());

    m_graphicsLayer->setPreserves3D(false);

    m_platformLayer = m_graphicsLayer->platformLayer();
    ASSERT_TRUE(m_platformLayer);

    ASSERT_FALSE(m_platformLayer->hasActiveAnimation());
}

class FakeScrollableArea : public ScrollableArea {
public:
    virtual bool isActive() const OVERRIDE { return false; }
    virtual int scrollSize(ScrollbarOrientation) const OVERRIDE { return 100; }
    virtual int scrollPosition(Scrollbar*) const OVERRIDE { return 0; }
    virtual bool isScrollCornerVisible() const OVERRIDE { return false; }
    virtual IntRect scrollCornerRect() const OVERRIDE { return IntRect(); }
    virtual int visibleWidth() const OVERRIDE { return 10; }
    virtual int visibleHeight() const OVERRIDE { return 10; }
    virtual IntSize contentsSize() const OVERRIDE { return IntSize(100, 100); }
    virtual bool scrollbarsCanBeActive() const OVERRIDE { return false; }
    virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE { return 0; }
    virtual IntRect scrollableAreaBoundingBox() const OVERRIDE { return IntRect(); }
    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE { }
    virtual void invalidateScrollCornerRect(const IntRect&) OVERRIDE { }

    virtual void setScrollOffset(const IntPoint& scrollOffset) OVERRIDE { m_scrollPosition = scrollOffset; }
    virtual IntPoint scrollPosition() const OVERRIDE { return m_scrollPosition; }

private:
    IntPoint m_scrollPosition;
};

// http://crbug.com/247279
TEST_F(GraphicsLayerTest, DISABLED_applyScrollToScrollableArea)
{
    FakeScrollableArea scrollableArea;
    m_graphicsLayer->setScrollableArea(&scrollableArea);

    WebPoint scrollPosition(7, 9);
    m_platformLayer->setScrollPosition(scrollPosition);

    EXPECT_EQ(scrollPosition, WebPoint(scrollableArea.scrollPosition()));
}

TEST_F(GraphicsLayerTest, DISABLED_setContentsToSolidColor)
{
    m_graphicsLayer->setContentsToSolidColor(Color::transparent);
    EXPECT_FALSE(m_graphicsLayer->contentsLayer());

    m_graphicsLayer->setContentsToSolidColor(Color::white);
    EXPECT_TRUE(m_graphicsLayer->contentsLayer());

    m_graphicsLayer->setContentsToSolidColor(Color());
    EXPECT_FALSE(m_graphicsLayer->contentsLayer());
}

} // namespace
<|endoftext|>


<commit_before>#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QVBoxLayout>

#include "api.hpp"
#include "common/params.h"
#include "drive_stats.hpp"

const double MILE_TO_KM = 1.60934;

static QLayout* build_stat_layout(QLabel** metric, const QString& name) {
  QVBoxLayout* layout = new QVBoxLayout;
  layout->setMargin(0);
  *metric = new QLabel("0");
  (*metric)->setStyleSheet("font-size: 80px; font-weight: 600;");
  layout->addWidget(*metric, 0, Qt::AlignLeft);

  QLabel* label = new QLabel(name);
  label->setStyleSheet("font-size: 45px; font-weight: 500;");
  layout->addWidget(label, 0, Qt::AlignLeft);
  return layout;
}

void DriveStats::parseResponse(QString response) {
  response = response.trimmed();
  QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
  if (doc.isNull()) {
    qDebug() << "JSON Parse failed on getting past drives statistics";
    return;
  }

  auto update = [](const QJsonObject &obj, StatsLabels& labels, bool metric) {
    labels.routes->setText(QString::number((int)obj["routes"].toDouble()));
    labels.distance->setText(QString::number(obj["distance"].toDouble() * (metric ? MILE_TO_KM : 1)));
    labels.hours->setText(QString::number((int)(obj["minutes"].toDouble() / 60)));
  };

  bool metric = Params().read_db_bool("IsMetric");
  QJsonObject json = doc.object();
  update(json["all"].toObject(), all_, metric);
  update(json["week"].toObject(), week_, metric);
}

DriveStats::DriveStats(QWidget* parent) : QWidget(parent) {
  setStyleSheet("QLabel {font-size: 48px; font-weight: 500;}");

  auto add_stats_layouts = [&](QGridLayout* gl, StatsLabels& labels, int row, const char* distance_unit) {
    gl->addLayout(build_stat_layout(&labels.routes, "DRIVES"), row, 0, 3, 1);
    gl->addLayout(build_stat_layout(&labels.distance, distance_unit), row, 1, 3, 1);
    gl->addLayout(build_stat_layout(&labels.hours, "HOURS"), row, 2, 3, 1);
  };

  const char* distance_unit = Params().read_db_bool("IsMetric") ? "KM" : "MILES";
  QGridLayout* gl = new QGridLayout();
  gl->setMargin(0);
  gl->addWidget(new QLabel("ALL TIME"), 0, 0, 1, 3);
  add_stats_layouts(gl, all_, 1, distance_unit);
  gl->addWidget(new QLabel("PAST WEEK"), 6, 0, 1, 3);
  add_stats_layouts(gl, week_, 7, distance_unit);

  QVBoxLayout* vlayout = new QVBoxLayout(this);
  vlayout->addLayout(gl);

  // TODO: do we really need to update this frequently?
  QString dongleId = QString::fromStdString(Params().get("DongleId"));
  QString url = "https://api.commadotai.com/v1.1/devices/" + dongleId + "/stats";
  RequestRepeater* repeater = new RequestRepeater(this, url, 13, "ApiCache_DriveStats");
  QObject::connect(repeater, SIGNAL(receivedResponse(QString)), this, SLOT(parseResponse(QString)));
}
<commit_msg>drive_stats.cc: fix distance rounding<commit_after>#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QVBoxLayout>

#include "api.hpp"
#include "common/params.h"
#include "drive_stats.hpp"

const double MILE_TO_KM = 1.60934;

static QLayout* build_stat_layout(QLabel** metric, const QString& name) {
  QVBoxLayout* layout = new QVBoxLayout;
  layout->setMargin(0);
  *metric = new QLabel("0");
  (*metric)->setStyleSheet("font-size: 80px; font-weight: 600;");
  layout->addWidget(*metric, 0, Qt::AlignLeft);

  QLabel* label = new QLabel(name);
  label->setStyleSheet("font-size: 45px; font-weight: 500;");
  layout->addWidget(label, 0, Qt::AlignLeft);
  return layout;
}

void DriveStats::parseResponse(QString response) {
  response = response.trimmed();
  QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());
  if (doc.isNull()) {
    qDebug() << "JSON Parse failed on getting past drives statistics";
    return;
  }

  auto update = [](const QJsonObject &obj, StatsLabels& labels, bool metric) {
    labels.routes->setText(QString::number((int)obj["routes"].toDouble()));
    labels.distance->setText(QString::number(int(obj["distance"].toDouble() * (metric ? MILE_TO_KM : 1))));
    labels.hours->setText(QString::number((int)(obj["minutes"].toDouble() / 60)));
  };

  bool metric = Params().read_db_bool("IsMetric");
  QJsonObject json = doc.object();
  update(json["all"].toObject(), all_, metric);
  update(json["week"].toObject(), week_, metric);
}

DriveStats::DriveStats(QWidget* parent) : QWidget(parent) {
  setStyleSheet("QLabel {font-size: 48px; font-weight: 500;}");

  auto add_stats_layouts = [&](QGridLayout* gl, StatsLabels& labels, int row, const char* distance_unit) {
    gl->addLayout(build_stat_layout(&labels.routes, "DRIVES"), row, 0, 3, 1);
    gl->addLayout(build_stat_layout(&labels.distance, distance_unit), row, 1, 3, 1);
    gl->addLayout(build_stat_layout(&labels.hours, "HOURS"), row, 2, 3, 1);
  };

  const char* distance_unit = Params().read_db_bool("IsMetric") ? "KM" : "MILES";
  QGridLayout* gl = new QGridLayout();
  gl->setMargin(0);
  gl->addWidget(new QLabel("ALL TIME"), 0, 0, 1, 3);
  add_stats_layouts(gl, all_, 1, distance_unit);
  gl->addWidget(new QLabel("PAST WEEK"), 6, 0, 1, 3);
  add_stats_layouts(gl, week_, 7, distance_unit);

  QVBoxLayout* vlayout = new QVBoxLayout(this);
  vlayout->addLayout(gl);

  // TODO: do we really need to update this frequently?
  QString dongleId = QString::fromStdString(Params().get("DongleId"));
  QString url = "https://api.commadotai.com/v1.1/devices/" + dongleId + "/stats";
  RequestRepeater* repeater = new RequestRepeater(this, url, 13, "ApiCache_DriveStats");
  QObject::connect(repeater, SIGNAL(receivedResponse(QString)), this, SLOT(parseResponse(QString)));
}
<|endoftext|>


<commit_before><commit_msg>fixed: INVALID_COEFFICIENTS<commit_after><|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkOrImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <itkImage.h>
#include <itkNumericTraits.h>
#include <itkOrImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>

int itkOrImageFilterTest(int, char* [] )
{

  // Define the dimension of the images
  const unsigned int myDimension = 3;

  // Declare the types of the images
  typedef unsigned char myPixelType;
  typedef itk::Image<myPixelType, myDimension>  myImageType1;
  typedef itk::Image<myPixelType, myDimension>  myImageType2;
  typedef itk::Image<myPixelType, myDimension>  myImageType3;

  // Declare the type of the index to access images
  typedef itk::Index<myDimension>         myIndexType;

  // Declare the type of the size
  typedef itk::Size<myDimension>          mySizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion<myDimension>        myRegionType;

  // Declare the type for the ADD filter
  typedef itk::OrImageFilter<
                                myImageType1,
                                myImageType2,
                                myImageType3  >       myFilterType;

  // Declare the pointers to images
  typedef myImageType1::Pointer   myImageType1Pointer;
  typedef myImageType2::Pointer   myImageType2Pointer;
  typedef myImageType3::Pointer   myImageType3Pointer;
  typedef myFilterType::Pointer   myFilterTypePointer;

  // Create two images
  myImageType1Pointer inputImageA  = myImageType1::New();
  myImageType2Pointer inputImageB  = myImageType2::New();

  // Define their size, and start index
  mySizeType size;
  size[0] = 2;
  size[1] = 2;
  size[2] = 2;

  myIndexType start;
  start[0] = 0;
  start[1] = 0;
  start[2] = 0;

  myRegionType region;
  region.SetIndex( start );
  region.SetSize( size );

  // Initialize Image A
  inputImageA->SetLargestPossibleRegion( region );
  inputImageA->SetBufferedRegion( region );
  inputImageA->SetRequestedRegion( region );
  inputImageA->Allocate();

  // Initialize Image B
  inputImageB->SetLargestPossibleRegion( region );
  inputImageB->SetBufferedRegion( region );
  inputImageB->SetRequestedRegion( region );
  inputImageB->Allocate();

  // Declare Iterator types apropriated for each image
  typedef itk::ImageRegionIteratorWithIndex<myImageType1>  myIteratorType1;
  typedef itk::ImageRegionIteratorWithIndex<myImageType2>  myIteratorType2;
  typedef itk::ImageRegionIteratorWithIndex<myImageType3>  myIteratorType3;

  // Create one iterator for Image A (this is a light object)
  myIteratorType1 it1( inputImageA, inputImageA->GetBufferedRegion() );

  // Initialize the content of Image A
  std::cout << "First operand " << std::endl;
  while( !it1.IsAtEnd() )
  {
    it1.Set( 2.0 );
    std::cout << static_cast<itk::NumericTraits<myPixelType>::PrintType>(it1.Get()) << std::endl;
    ++it1;
  }

  // Create one iterator for Image B (this is a light object)
  myIteratorType2 it2( inputImageB, inputImageB->GetBufferedRegion() );

  // Initialize the content of Image B
  std::cout << "Second operand " << std::endl;
  while( !it2.IsAtEnd() )
  {
    it2.Set( 3.0 );
    std::cout << static_cast<itk::NumericTraits<myPixelType>::PrintType>(it2.Get()) << std::endl;
    ++it2;
  }

  // Create an ADD Filter
  myFilterTypePointer filter = myFilterType::New();

  // Connect the input images
  filter->SetInput1( inputImageA );
  filter->SetInput2( inputImageB );

  // Get the Smart Pointer to the Filter Output
  myImageType3Pointer outputImage = filter->GetOutput();

  // Execute the filter
  filter->Update();

  // Create an iterator for going through the image output
  myIteratorType3 it3(outputImage, outputImage->GetBufferedRegion());

  //  Print the content of the result image
  std::cout << " Result " << std::endl;
  while( !it3.IsAtEnd() )
  {
    std::cout << static_cast<itk::NumericTraits<myPixelType>::PrintType>(it3.Get()) << std::endl;
    ++it3;
  }

  // All objects should be automatically destroyed at this point
  std::cout << "Test PASSED !" << std::endl;

  return EXIT_SUCCESS;

}

<commit_msg>ENH: GoToBegin() calls where missing in iterators.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkOrImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <itkImage.h>
#include <itkNumericTraits.h>
#include <itkOrImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>

int itkOrImageFilterTest(int, char* [] )
{

  // Define the dimension of the images
  const unsigned int myDimension = 3;

  // Declare the types of the images
  typedef unsigned char myPixelType;
  typedef itk::Image<myPixelType, myDimension>  myImageType1;
  typedef itk::Image<myPixelType, myDimension>  myImageType2;
  typedef itk::Image<myPixelType, myDimension>  myImageType3;

  // Declare the type of the index to access images
  typedef itk::Index<myDimension>         myIndexType;

  // Declare the type of the size
  typedef itk::Size<myDimension>          mySizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion<myDimension>        myRegionType;

  // Declare the type for the ADD filter
  typedef itk::OrImageFilter<
                                myImageType1,
                                myImageType2,
                                myImageType3  >       myFilterType;

  // Declare the pointers to images
  typedef myImageType1::Pointer   myImageType1Pointer;
  typedef myImageType2::Pointer   myImageType2Pointer;
  typedef myImageType3::Pointer   myImageType3Pointer;
  typedef myFilterType::Pointer   myFilterTypePointer;

  // Create two images
  myImageType1Pointer inputImageA  = myImageType1::New();
  myImageType2Pointer inputImageB  = myImageType2::New();

  // Define their size, and start index
  mySizeType size;
  size[0] = 2;
  size[1] = 2;
  size[2] = 2;

  myIndexType start;
  start[0] = 0;
  start[1] = 0;
  start[2] = 0;

  myRegionType region;
  region.SetIndex( start );
  region.SetSize( size );

  // Initialize Image A
  inputImageA->SetLargestPossibleRegion( region );
  inputImageA->SetBufferedRegion( region );
  inputImageA->SetRequestedRegion( region );
  inputImageA->Allocate();

  // Initialize Image B
  inputImageB->SetLargestPossibleRegion( region );
  inputImageB->SetBufferedRegion( region );
  inputImageB->SetRequestedRegion( region );
  inputImageB->Allocate();

  // Declare Iterator types apropriated for each image
  typedef itk::ImageRegionIteratorWithIndex<myImageType1>  myIteratorType1;
  typedef itk::ImageRegionIteratorWithIndex<myImageType2>  myIteratorType2;
  typedef itk::ImageRegionIteratorWithIndex<myImageType3>  myIteratorType3;

  // Create one iterator for Image A (this is a light object)
  myIteratorType1 it1( inputImageA, inputImageA->GetBufferedRegion() );
  it1.GoToBegin();

  // Initialize the content of Image A
  std::cout << "First operand " << std::endl;
  while( !it1.IsAtEnd() )
  {
    it1.Set( 2.0 );
    std::cout << static_cast<itk::NumericTraits<myPixelType>::PrintType>(it1.Get()) << std::endl;
    ++it1;
  }

  // Create one iterator for Image B (this is a light object)
  myIteratorType2 it2( inputImageB, inputImageB->GetBufferedRegion() );
  it2.GoToBegin();

  // Initialize the content of Image B
  std::cout << "Second operand " << std::endl;
  while( !it2.IsAtEnd() )
  {
    it2.Set( 3.0 );
    std::cout << static_cast<itk::NumericTraits<myPixelType>::PrintType>(it2.Get()) << std::endl;
    ++it2;
  }

  // Create an ADD Filter
  myFilterTypePointer filter = myFilterType::New();

  // Connect the input images
  filter->SetInput1( inputImageA );
  filter->SetInput2( inputImageB );

  // Get the Smart Pointer to the Filter Output
  myImageType3Pointer outputImage = filter->GetOutput();

  // Execute the filter
  filter->Update();

  // Create an iterator for going through the image output
  myIteratorType3 it3(outputImage, outputImage->GetBufferedRegion());
  it3.GoToBegin();

  //  Print the content of the result image
  std::cout << " Result " << std::endl;
  while( !it3.IsAtEnd() )
  {
    std::cout << static_cast<itk::NumericTraits<myPixelType>::PrintType>(it3.Get()) << std::endl;
    ++it3;
  }

  // All objects should be automatically destroyed at this point
  std::cout << "Test PASSED !" << std::endl;

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/**
 * Plan of Attack
 * * identify functions to test
 * * plan out test fixtures and structure
 * * set up test class
 *
 */

/**
 * Functions to test:
 * int co_profiles_create(const size_t index_size); +
 * int co_profiles_init(const size_t index_size); +
 * co_obj_t *co_profile_find(co_obj_t *name); +
 * int co_profile_add(const char *name, const size_t nlen); +
 * int co_profile_remove(const char *name, const size_t nlen); +
 * co_obj_t *co_profile_get(co_obj_t *profile, const co_obj_t *key);
 * size_t co_profile_get_str(co_obj_t *profile, char **output, const char *key, const size_t klen);
 * int co_profile_set_str(co_obj_t *profile, const char *key, const size_t klen, const char *value, const size_t vlen);
 *
 *
 */

extern "C" {
#include "../src/obj.h"
#include "../src/list.h"
#include "../src/tree.h"
#include "../src/profile.h"
}
#include "gtest/gtest.h"

SCHEMA(default)
{
  SCHEMA_ADD("ssid", "commotionwireless.net");
  SCHEMA_ADD("bssid", "02:CA:FF:EE:BA:BE");
  SCHEMA_ADD("bssidgen", "true");
  SCHEMA_ADD("channel", "5");
  SCHEMA_ADD("mode", "adhoc");
  SCHEMA_ADD("type", "mesh");
  SCHEMA_ADD("dns", "208.67.222.222");
  SCHEMA_ADD("domain", "mesh.local");
  SCHEMA_ADD("ipgen", "true");
  SCHEMA_ADD("ip", "100.64.0.0");
  SCHEMA_ADD("netmask", "255.192.0.0");
  SCHEMA_ADD("ipgenmask", "255.192.0.0");
  SCHEMA_ADD("encryption", "psk2");
  SCHEMA_ADD("key", "c0MM0t10n!r0cks");
  SCHEMA_ADD("serval", "false");
  SCHEMA_ADD("announce", "true");
  return 1;
}

class ProfileTest : public ::testing::Test
{
protected:
  // test functions
  void Init();
  void Add();
  void Retrieve();
  void Remove();
  void Get();

  // variables
  int ret = 0;
  co_obj_t *profile1 = co_str8_create("profile1", 9, 0);
  co_obj_t *profile2 = co_str8_create("profile2", 9, 0);
  co_obj_t *found = NULL;

  // constructor
  ProfileTest()
  {
    ret = co_profiles_init(16);
  }

  virtual void SetUp()
  {
  }

  ~ProfileTest()
  {
  }
};

void ProfileTest::Init()
{
  ASSERT_EQ(1, ret);
}

void ProfileTest::Add()
{
  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);
}

void ProfileTest::Retrieve()
{
  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);

  ret = co_profile_add("profile2", 9);
  ASSERT_EQ(1, ret);

  found = co_profile_find(profile1);
  ASSERT_TRUE(NULL != found);

  found = co_profile_find(profile2);
  ASSERT_TRUE(NULL != found);
}

void ProfileTest::Remove()
{
  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);

  ret = co_profile_add("profile2", 9);
  ASSERT_EQ(1, ret);

  ret = co_profile_remove("profile1", 9);
  ASSERT_EQ(1, ret);

  // confirm removal
  found = co_profile_find(profile1);
  ASSERT_TRUE(NULL == found);

  ret = co_profile_remove("profile2", 9);
  ASSERT_EQ(1, ret);

  //confirm removal
  found = co_profile_find(profile2);
  ASSERT_TRUE(NULL == found);
}

void ProfileTest::Get()
{
  SCHEMA_REGISTER(default);

  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);

  found = co_profile_find(profile1);
  ASSERT_TRUE(NULL != found);

  ret = co_profile_set_str((co_obj_t *)found, "ip", sizeof("ip"), "192.168.1.254", sizeof("192.168.1.254"));
  ASSERT_EQ(1, ret);

//   ret = co_profile_get_str(profile1, &ip, "ip", sizeof("ip");
//   ASSERT_TRUE(NULL != ret);
}

TEST_F(ProfileTest, Init)
{
  Init();
}

TEST_F(ProfileTest, Add)
{
  Add();
}

TEST_F(ProfileTest, Retrieve)
{
  Retrieve();
}

TEST_F(ProfileTest, Remove)
{
  Remove();
}

TEST_F(ProfileTest, Get)
{
  Get();
}<commit_msg>improved set/get tests<commit_after>/**
 * Plan of Attack
 * * identify functions to test
 * * plan out test fixtures and structure
 * * set up test class
 *
 */

/**
 * Functions to test:
 * int co_profiles_create(const size_t index_size); +
 * int co_profiles_init(const size_t index_size); +
 * co_obj_t *co_profile_find(co_obj_t *name); +
 * int co_profile_add(const char *name, const size_t nlen); +
 * int co_profile_remove(const char *name, const size_t nlen); +
 * co_obj_t *co_profile_get(co_obj_t *profile, const co_obj_t *key);
 * size_t co_profile_get_str(co_obj_t *profile, char **output, const char *key, const size_t klen);
 * int co_profile_set_str(co_obj_t *profile, const char *key, const size_t klen, const char *value, const size_t vlen);
 *
 *
 */

extern "C" {
#include "../src/obj.h"
#include "../src/list.h"
#include "../src/tree.h"
#include "../src/profile.h"
}
#include "gtest/gtest.h"

SCHEMA(default)
{
  SCHEMA_ADD("ssid", "commotionwireless.net");
  SCHEMA_ADD("bssid", "02:CA:FF:EE:BA:BE");
  SCHEMA_ADD("bssidgen", "true");
  SCHEMA_ADD("channel", "5");
  SCHEMA_ADD("mode", "adhoc");
  SCHEMA_ADD("type", "mesh");
  SCHEMA_ADD("dns", "208.67.222.222");
  SCHEMA_ADD("domain", "mesh.local");
  SCHEMA_ADD("ipgen", "true");
  SCHEMA_ADD("ip", "100.64.0.0");
  SCHEMA_ADD("netmask", "255.192.0.0");
  SCHEMA_ADD("ipgenmask", "255.192.0.0");
  SCHEMA_ADD("encryption", "psk2");
  SCHEMA_ADD("key", "c0MM0t10n!r0cks");
  SCHEMA_ADD("serval", "false");
  SCHEMA_ADD("announce", "true");
  return 1;
}

class ProfileTest : public ::testing::Test
{
protected:
  // test functions
  void Init();
  void Add();
  void Retrieve();
  void Remove();
  void Get();

  // variables
  int ret = 0;
  co_obj_t *profile1 = co_str8_create("profile1", 9, 0);
  co_obj_t *profile2 = co_str8_create("profile2", 9, 0);
  co_obj_t *found = NULL;

  // constructor
  ProfileTest()
  {
    ret = co_profiles_init(16);
  }

  virtual void SetUp()
  {
  }

  ~ProfileTest()
  {
  }
};

void ProfileTest::Init()
{
  ASSERT_EQ(1, ret);
}

void ProfileTest::Add()
{
  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);
}

void ProfileTest::Retrieve()
{
  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);

  ret = co_profile_add("profile2", 9);
  ASSERT_EQ(1, ret);

  found = co_profile_find(profile1);
  ASSERT_TRUE(NULL != found);

  found = co_profile_find(profile2);
  ASSERT_TRUE(NULL != found);
}

void ProfileTest::Remove()
{
  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);

  ret = co_profile_add("profile2", 9);
  ASSERT_EQ(1, ret);

  ret = co_profile_remove("profile1", 9);
  ASSERT_EQ(1, ret);

  // confirm removal
  found = co_profile_find(profile1);
  ASSERT_TRUE(NULL == found);

  ret = co_profile_remove("profile2", 9);
  ASSERT_EQ(1, ret);

  //confirm removal
  found = co_profile_find(profile2);
  ASSERT_TRUE(NULL == found);
}

void ProfileTest::Get()
{

  SCHEMA_REGISTER(default);

  ret = co_profile_add("profile1", 9);
  ASSERT_EQ(1, ret);

  found = co_profile_find(profile1);
  ASSERT_TRUE(NULL != found);

  ret = co_profile_set_str((co_obj_t *)found, "ip", sizeof("ip"), "192.168.1.254", sizeof("192.168.1.254"));
  ASSERT_EQ(1, ret);

  char *ip;

  ret = co_profile_get_str(found, &ip, "ip", sizeof("ip"));
  ASSERT_STREQ("192.168.1.254", ip);
}

TEST_F(ProfileTest, Init)
{
  Init();
}

TEST_F(ProfileTest, Add)
{
  Add();
}

TEST_F(ProfileTest, Retrieve)
{
  Retrieve();
}

TEST_F(ProfileTest, Remove)
{
  Remove();
}

TEST_F(ProfileTest, Get)
{
  Get();
}<|endoftext|>


<commit_before>#include "config.h"
#include "halcmd_rtapiapp.h"

#include <czmq.h>
#include <string.h>
#include "ll-zeroconf.hh"
#include "mk-zeroconf.hh"
#include "mk-zeroconf-types.h"
#include <avahi-common/malloc.h>

#include <machinetalk/generated/message.pb.h>
using namespace google::protobuf;

static pb::Container command, reply;

static zctx_t *z_context;
static void *z_command;
static int timeout = 5000;
static std::string errormsg;

int rtapi_rpc(void *socket, pb::Container &tx, pb::Container &rx)
{
    zframe_t *request = zframe_new (NULL, tx.ByteSize());
    assert(request);
    assert(tx.SerializeWithCachedSizesToArray(zframe_data (request)));

    assert (zframe_send (&request, socket, 0) == 0);
    zframe_t *reply = zframe_recv (socket);
    if (reply == NULL) {
	errormsg =  "rtapi_rpc(): reply timeout";
	return -1;
    }
    int retval =  rx.ParseFromArray(zframe_data (reply),
				    zframe_size (reply)) ? 0 : -1;
    //    assert(retval == 0);
    zframe_destroy(&reply);

    errormsg = "";
    for (int i = 0; i < rx.note_size(); i++)
	errormsg += rx.note(i) + "\n";
    return retval;
}

int rtapi_callfunc(int instance,
		   const char *func,
		   const char **args)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_CALLFUNC);
    cmd = command.mutable_rtapicmd();
    cmd->set_func(func);
    cmd->set_instance(instance);

    int argc = 0;
    if (args)
	while(args[argc] && *args[argc]) {
	    cmd->add_argv(args[argc]);
	    argc++;
	}
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_newinst(int instance,
		  const char *comp,
		  const char *instname,
		  const char **args)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_NEWINST);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);

    cmd->set_comp(comp);
    cmd->set_instname(instname);

    int argc = 0;
    if (args)
	while(args[argc] && *args[argc]) {
	    cmd->add_argv(args[argc]);
	    argc++;
	}
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_delinst(int instance,
		  const char *instname)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_DELINST);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);
    cmd->set_instname(instname);
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();

}

static int rtapi_loadop(pb::ContainerType type, int instance, const char *modname, const char **args)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(type);
    cmd = command.mutable_rtapicmd();
    cmd->set_modname(modname);
    cmd->set_instance(instance);

    int argc = 0;
    if (args)
	while(args[argc] && *args[argc]) {
	    cmd->add_argv(args[argc]);
	    argc++;
	}
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_loadrt(int instance, const char *modname, const char **args)
{
    return rtapi_loadop(pb::MT_RTAPI_APP_LOADRT, instance, modname, args);
}

int rtapi_unloadrt(int instance, const char *modname)
{
    return rtapi_loadop(pb::MT_RTAPI_APP_UNLOADRT, instance, modname, NULL);
}

int rtapi_shutdown(int instance)
{
    pb::RTAPICommand *cmd;

    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_EXIT);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);

    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_ping(int instance)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_PING);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);

    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_newthread(int instance, const char *name, int period, int cpu, int use_fp)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_NEWTHREAD);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);
    cmd->set_threadname(name);
    cmd->set_threadperiod(period);
    cmd->set_cpu(cpu);
    cmd->set_use_fp(use_fp);

    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_delthread(int instance, const char *name)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_DELTHREAD);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);
    cmd->set_threadname(name);
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

const char *rtapi_rpcerror(void)
{
    return errormsg.c_str();
}

int rtapi_connect(int instance, char *uri, const char *svc_uuid)
{
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    char ipcuri[100];

    if (uri == NULL) {
	snprintf(ipcuri, sizeof(ipcuri),ZMQIPC_FORMAT,
		 RUNDIR, instance, "rtapi", svc_uuid);
	uri = ipcuri;
    }

#if 0
    // we're not doing remote RTAPI just yet
    if (uri == NULL) {
	char uuid[50];
	snprintf(uuid, sizeof(uuid),"uuid=%s", svc_uuid);

	zresolve_t res = {0};
	res.proto =	 AVAHI_PROTO_UNSPEC;
	res.interface = AVAHI_IF_UNSPEC;
	res.type =  (char *) RTAPI_DNSSD_SUBTYPE   MACHINEKIT_DNSSD_SERVICE_TYPE;
	res.match = uuid;
	res.domain = NULL;
	res.name = (char *)"";
	res.timeout_ms = 3000;
	res.result = SD_UNSET;

	resolve_context_t *p  = ll_zeroconf_resolve(&res);

	if (res.result == SD_OK) {
	    // fish out the dsn=<uri> TXT record

	    AvahiStringList *dsn = avahi_string_list_find(res.txt, "dsn");
	    char *key;
	    size_t vlen;

	    if (avahi_string_list_get_pair(dsn, &key, &uri, &vlen)) {
		fprintf(stderr,
			"halcmd: service discovery failed - no dsn= key\n");
		return -1;
	    }
	} else {
	    fprintf(stderr,
		    "halcmd: service discovery failed - cant retrieve rtapi_app command uri: %d\n",
		    res.result );
	    return -1;
	}
	ll_zeroconf_resolve_free(p);
    }
#endif

    z_context = zctx_new ();
    assert(z_context);
    z_command = zsocket_new (z_context, ZMQ_DEALER);
    assert(z_command);

    char z_ident[30];
    snprintf(z_ident, sizeof(z_ident), "halcmd%d",getpid());

    zsocket_set_identity(z_command, z_ident);
    zsocket_set_linger(z_command, 0);

    if (zsocket_connect(z_command, uri)) {
	perror("connect");
	return -EINVAL;
    }
    zsocket_set_rcvtimeo (z_command, timeout * ZMQ_POLL_MSEC);

    return rtapi_ping(instance);
}
<commit_msg>halcmd_rtapiapp.cc: concatenate all notes into a multiline error string<commit_after>#include "config.h"
#include "halcmd_rtapiapp.h"

#include <czmq.h>
#include <string.h>
#include "ll-zeroconf.hh"
#include "mk-zeroconf.hh"
#include "mk-zeroconf-types.h"
#include "pbutil.hh"
#include <avahi-common/malloc.h>

#include <machinetalk/generated/message.pb.h>
using namespace google::protobuf;

static pb::Container command, reply;

static zctx_t *z_context;
static void *z_command;
static int timeout = 5000;
static std::string errormsg;

int rtapi_rpc(void *socket, pb::Container &tx, pb::Container &rx)
{
    zframe_t *request = zframe_new (NULL, tx.ByteSize());
    assert(request);
    assert(tx.SerializeWithCachedSizesToArray(zframe_data (request)));

    assert (zframe_send (&request, socket, 0) == 0);
    zframe_t *reply = zframe_recv (socket);
    if (reply == NULL) {
	errormsg =  "rtapi_rpc(): reply timeout";
	return -1;
    }
    int retval =  rx.ParseFromArray(zframe_data (reply),
				    zframe_size (reply)) ? 0 : -1;
    //    assert(retval == 0);
    zframe_destroy(&reply);
    if (rx.note_size())
	errormsg = pbconcat(rx.note(), "\n");
    //errormsg = rx.note(0); // simplify - one line only
    else
	errormsg = "";
    return retval;
}

int rtapi_callfunc(int instance,
		   const char *func,
		   const char **args)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_CALLFUNC);
    cmd = command.mutable_rtapicmd();
    cmd->set_func(func);
    cmd->set_instance(instance);

    int argc = 0;
    if (args)
	while(args[argc] && *args[argc]) {
	    cmd->add_argv(args[argc]);
	    argc++;
	}
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_newinst(int instance,
		  const char *comp,
		  const char *instname,
		  const char **args)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_NEWINST);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);

    cmd->set_comp(comp);
    cmd->set_instname(instname);

    int argc = 0;
    if (args)
	while(args[argc] && *args[argc]) {
	    cmd->add_argv(args[argc]);
	    argc++;
	}
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_delinst(int instance,
		  const char *instname)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_DELINST);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);
    cmd->set_instname(instname);
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();

}

static int rtapi_loadop(pb::ContainerType type, int instance, const char *modname, const char **args)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(type);
    cmd = command.mutable_rtapicmd();
    cmd->set_modname(modname);
    cmd->set_instance(instance);

    int argc = 0;
    if (args)
	while(args[argc] && *args[argc]) {
	    cmd->add_argv(args[argc]);
	    argc++;
	}
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_loadrt(int instance, const char *modname, const char **args)
{
    return rtapi_loadop(pb::MT_RTAPI_APP_LOADRT, instance, modname, args);
}

int rtapi_unloadrt(int instance, const char *modname)
{
    return rtapi_loadop(pb::MT_RTAPI_APP_UNLOADRT, instance, modname, NULL);
}

int rtapi_shutdown(int instance)
{
    pb::RTAPICommand *cmd;

    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_EXIT);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);

    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_ping(int instance)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_PING);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);

    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_newthread(int instance, const char *name, int period, int cpu, int use_fp)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_NEWTHREAD);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);
    cmd->set_threadname(name);
    cmd->set_threadperiod(period);
    cmd->set_cpu(cpu);
    cmd->set_use_fp(use_fp);

    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

int rtapi_delthread(int instance, const char *name)
{
    pb::RTAPICommand *cmd;
    command.Clear();
    command.set_type(pb::MT_RTAPI_APP_DELTHREAD);
    cmd = command.mutable_rtapicmd();
    cmd->set_instance(instance);
    cmd->set_threadname(name);
    int retval = rtapi_rpc(z_command, command, reply);
    if (retval)
	return retval;
    return reply.retcode();
}

const char *rtapi_rpcerror(void)
{
    return errormsg.c_str();
}

int rtapi_connect(int instance, char *uri, const char *svc_uuid)
{
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    char ipcuri[100];

    if (uri == NULL) {
	snprintf(ipcuri, sizeof(ipcuri),ZMQIPC_FORMAT,
		 RUNDIR, instance, "rtapi", svc_uuid);
	uri = ipcuri;
    }

#if 0
    // we're not doing remote RTAPI just yet
    if (uri == NULL) {
	char uuid[50];
	snprintf(uuid, sizeof(uuid),"uuid=%s", svc_uuid);

	zresolve_t res = {0};
	res.proto =	 AVAHI_PROTO_UNSPEC;
	res.interface = AVAHI_IF_UNSPEC;
	res.type =  (char *) RTAPI_DNSSD_SUBTYPE   MACHINEKIT_DNSSD_SERVICE_TYPE;
	res.match = uuid;
	res.domain = NULL;
	res.name = (char *)"";
	res.timeout_ms = 3000;
	res.result = SD_UNSET;

	resolve_context_t *p  = ll_zeroconf_resolve(&res);

	if (res.result == SD_OK) {
	    // fish out the dsn=<uri> TXT record

	    AvahiStringList *dsn = avahi_string_list_find(res.txt, "dsn");
	    char *key;
	    size_t vlen;

	    if (avahi_string_list_get_pair(dsn, &key, &uri, &vlen)) {
		fprintf(stderr,
			"halcmd: service discovery failed - no dsn= key\n");
		return -1;
	    }
	} else {
	    fprintf(stderr,
		    "halcmd: service discovery failed - cant retrieve rtapi_app command uri: %d\n",
		    res.result );
	    return -1;
	}
	ll_zeroconf_resolve_free(p);
    }
#endif

    z_context = zctx_new ();
    assert(z_context);
    z_command = zsocket_new (z_context, ZMQ_DEALER);
    assert(z_command);

    char z_ident[30];
    snprintf(z_ident, sizeof(z_ident), "halcmd%d",getpid());

    zsocket_set_identity(z_command, z_ident);
    zsocket_set_linger(z_command, 0);

    if (zsocket_connect(z_command, uri)) {
	perror("connect");
	return -EINVAL;
    }
    zsocket_set_rcvtimeo (z_command, timeout * ZMQ_POLL_MSEC);

    return rtapi_ping(instance);
}
<|endoftext|>