This document assumes you have followed the Apache Geode Code contribution instructions
see BUILDING.md
- Make your changes/add your feature/fix a bug.
- Test your feature branch changes.
- Check your formatting.
- Submit a pull request.
Before submitting a pull request all tests must pass. This includes all unit tests, integration tests, and acceptance tests. We are using CTest for running tests (please see the CTest documentation for further information) and Google Test as testing framework.
$ cd <clone>
$ cd build
$ cd cppcache/test/<Debug|Release|if needed>
$ ./apache-geode_unittests
There are two test suites of integration tests based on different testing frameworks. The old integration tests (stored in geode-native/cppcache/integration-test
) are based on a custom testing framework, and the newer ones (stored in geode-native/cppcache/integration/test
) are based on Google Test.
Old integration tests are deprecated. If your changes include the implementation of new integration test/s to be verified, they should be written using Google Test. If your change implies a significant change in one or more old test cases, you should create the equivalent test case/s using Google Test to substitute the old one/s instead of adapting them.
Both integration test suites can be executed together using CTest.
$ cd build/cppcache/integration-test
$ ctest --timeout 2000 -L STABLE -C <Debug|Release> -j1
Execution will take 2 hours approximately. It is possible to increase the number of jobs changing the value of -j
parameter (up to 4
) for running tests in parallel, although it may end up with failed tests that will need to be re-run sequentially. Standalone tests can also be run as follows:
$ cd build/cppcache/integration-test
$ ctest -R <test_name> -C <Debug|Release>
For example: $ ctest --timeout 2000 -L STABLE -C Release -R testCacheless -j1
.NET integration tests can be executed similarly from build/clicache/integration-test
.
Make sure Docker is installed as it is required for SNI Tests
$ cd <clone>
$ cd build/cppcache/integration/test
$ ctest -j1
It is possible to increase the number of jobs changing the value of -j
parameter for running tests in parallel, although it may end up with failed tests that will need to be re-run sequentially. Standalone tests can also be run as follows:
$ cd <clone>
$ cd build/cppcache/integration/test
$ ctest -R <test_name> -j1
For example: $ ctest -R AuthInitializeTest.putGetWithBasicAuth -j1
Notice that BasicIPv6Test
test is expected to fail due to IPv6 support is disabled by default. BUILDING.md explains how to enable it.
Acceptance tests is a new category of tests that are designed to test end to end connectivity of a geode-native client with a cloud based geode cluster that sits behind a proxy server.
These tests are stored in geode-native/cppcache/acceptance-test
and geode-native/clicache/acceptance-test
for C++ and .NET clients respectively. They utilize docker containers for the proxy server and geode servers. They are enabled during cmake configuration only if docker and docker-compose are found.
The acceptance tests can be run using ctest as follows. Note: Currently, the tests can only be run sequentially, hence the -j1 flag below.
For C++ clients:
$ cd <clone>
$ cd build/cppcache/acceptance-test
$ ctest -R <test_name> -j1
For .NET clients:
$ cd <clone>
$ cd build/clicache/acceptance-test
$ ctest -R <test_name> -j1
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>
When writing new or refactoring old code please make the following changes.
-
Prefer the use of
auto
C++ orvar
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 tostd::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 withstd::string
orstd::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
onstd::shared_ptr
withstd::dynamic_pointer_cast
. Same goes forstatic_cast
tostd::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); }