Contributing

This document assumes you have followed the Apache Geode Code contribution instructions

Building the code

see BUILDING.md

Next steps

  • Make your changes/add your feature/fix a bug.
  • Test your feature branch changes
  • Check your formatting
  • Submit a pull request

Testing

Before submitting a pull request the unit and integration tests must all pass. We are using CTest, (Please see the CTest documentation for further information.)

Running unit tests

$ cd <clone>
$ cd build
$ cd cppcache/test/<Debug|Release|if needed>
$ ./apache-geode_unittests

Running old integration tests

$ cd <clone>
$ cd build
$ cmake --build . --target run-integration-tests

Which is equivalent to running ctest directly:

$ cd build/cppcache/integration-test
$ ctest --timeout 2000 -L STABLE -C <Debug|Release> -R . -j1

This will take ~ 2 hours, YMMV... you can up the jobs to 4 and run in parallel, but you may end up with test failures that will need to be re-run sequentially. Like so:

$ cd build/cppcache/integration-test
$ ctest -R <test_name> -C <Debug|Release>

.NET integration tests can be executed similarly from build/clicache/integration-test.

Running new integration tests

$ cd <clone>
$ cd build
$ cd cppcache/integration/test
$ ./cpp-integration-test [<options>]

Note that are gtest options that may be passed to the test executable, like for example the test cases to be run. Use --help to get all the available options.

Style

Formatting C++

For C++ it is required to follow the Google C++ Style Guide and have a build target that uses clang-format to achieve compliance.

$ clang-format -i --style=file <PATH_TO_FILES>

Code

When writing new or refactoring old code please make the following changes.

  • Prefer the use of auto C++ or var in C# where applicable.

    std::vector<Cars> cars = lot.getCars();
    

    should be changed to

    auto cars = lot.getCars();
    
  • Prefer range for loops over traditional for loops where applicable.

    for (std::vector<Car>::iterator i = cars.begin(); i != cars.end(), ++i) {
      Car car = *i;
      std::cout << car.getName();
    }
    

    should be changed to

    for (const auto& car : cars) {
      std::cout << car.getName();
    }
    
  • Fix bad variable names. Variable names should be expressive.

    double i = car.getFuelLevel();
    

    should be changed to

    auto fuelLevel = car.getFuelLevel();
    
  • Use override on all method overrides.

    Given a base class

    class Base {
     public:
      Base();
      virtual ~Base();
      virtual virtualMethod();
      virtual pureVirtualMethod() = 0;
    }
    

    the derived class

    class Derived : public Base {
     public:
      virtual ~Derived();
      virtual virtualMethod();
      virtual pureVirtualMethod();
    }
    

    should be changed to

    class Derived : public Base {
     public:
      Derived();
      ~Derived() override;
      virtualMethod() override;
      pureVirtualMethod() override;
    }
    
  • Fix std::string::c_str() calls where passed to std::string parameters.

    auto name = std::string("Delorean");
    ...
    car.setName(name.c_str());
    

    should be changed to

    auto name = std::string("Delorean");
    ...
    car.setName(name);
    
  • Replace sprintf for logging messages with std::string or std::stringstream.

    char[1024] buffer;
    sprintf(buffer, "Car::crashed: name=%s", car.getName().c_str());
    LOG(buffer);
    

    should be changed to

    LOG("Car::crashed: name=" + car.getName());
    
  • Replace dynamic_cast on std::shared_ptr with std::dynamic_pointer_cast. Same goes for static_cast to std::static_pointer_cast, etc.

    std::shared_ptr<Car> car = garage.getCar();
    Delorean* delorean = dynamic_cast<Delorean*>(car.get());
    if (nullptr != delorean) {
      delorean->setSpeed(88);
    }
    

    should be changed to

    auto car = garage.getCar();
    if (auto delorean = std::dynamic_pointer_cast<Delorean>(car)) {
      delorean->setSpeed(88);
    }