Skip to content

Development guidelines

Alexander Krizhanovsky edited this page Apr 2, 2024 · 27 revisions

Coding style

Tempesta uses C, C++ and Python programming languages and all the code must obey the same coding style. We use the same coding style, slightly modified Linux kernel's one to be applicable to C++, for both the C and C++ code. Python code must obey standard coding style described in PEP-8 document.

Don't forget to check your code against common code smells before a commit.

Enable Git hooks:

git config --local core.hooksPath .githooks/

Development branches

We don't use standard Git branching workflow. Instead, we aim rapid features development and high reliability with release branches. There are 3 types of branches:

  1. master - current development (HEAD) branch, relatively unstable. All new features (issues labeled as enhancement) are here. It can be considered as alpha version.
  2. release (e.g. release-0.5.0) - quite stable branches. Only bugfixes (issues labeled as bug) are here. All bugs found in the branches get the crucial label and must be fixed ASAP.
  3. development (named with a developer initials, the issue number and short description, e.g. ak-1377-h2-fixes) - a personal developer branches, which at some point are merged into master.

master and release branches are protected, so a pull request must pass code review and all CI tests before being merged into the branches.

Every feature or bug fix must be developed in designated developer's branch. We name developer branches like ak-47 or ak-tdb where ak are initials of a developer and 47 or tdb is the issue number or name if it's not in github issues yet. When the work is done a pull request from the branch is created and published for a review. At least 2 other developers must agree with the change. When the pull request is approved, the developer merges it into the master branch.

Our team members create their development branches in the main, Tempesta FW repo, not forks. This makes code review of developer pull requests easier since a reviewer don't need to clone a new fork of the repo. Everyone (everyone in our team does code reviews) in our team don't need to keep repo clones of everyone. Pull request (and branch) from a cloned repo is a good and only the option for an external contributor, not a team member.

Bug fixes from the master branch can be merged to release branches as well. Basically, bug fixes must be applied to all supported releases (not reached end of life (EoL) state).

Commit messages and problem description

Please pay attention to commit messages. When you submit a commit, imagine a developer (or yourself say in one year from now) resolving a problem with the code and trying to understand the reason for the change.

If you found a bug and already fixed it, please make sure that the bug has a proper description either as Github issue or right in the commit message.

Pull requests with fixes commented just like

The function tfw_xyz() should not set flag ABC.

most likely will be requested for changes.

Versioning

Tempesta uses Semantic versioning. If you prepare a pull request with some fixes to release branch, e.g. release-0.5.0, please update the minor version in TFW_VERSION in tempesta/tempesta_fw/tempesta_fw.h, e.g. update it from "0.5.0" to "0.5.1".

Your pull request may contain several patches (commits) and only one of them changes the version, so please put a new version tag to the accumulated change. Thus, in the branch release-0.5.0 we'll have many tags for minor versions (patch levels): 0.5.1, 0.5.2 etc.

Testing

Developer testing

Unit and functional tests must be successfully executed by a developer before publishing a pull request for a review:

    $ cd tempesta && make test
    $ cd tempesta-test && ./run_tests.py

You can read more about functional tests in the README.

A developer must create a new test or an appropriate issue for the test for each bug fix, which wasn't found by the testing system, or a new feature.

Continuous integration (CI)

Continuous integration is closely linked with continuous testing, the subject of the section.

To avoid bottlenecks in the continuous delivery (CD) pipeline all the tests must be automated. The main difference between functional tests and CI tests is that origins can require complex environment setups (e.g. managing cluster nodes), longer time to run (e.g. tests for memory leaks) and powerful hardware (e.g. for performance testing).

We use two repositories for testing TempestaFW - tempesta-test and tempesta so you should use the same branch names in these repositories if you create/modify/enable tests in tempesta-test for your tempesta branch.

Current CI jobs from Jenkins:

(PR)tempesta
  1. Tempesta branch - branch from PR merged with master (or release-x.x.x branch);
  2. Test branch - branch from PR (if this branch exists in Tempesta-test repo or master);
  3. Stages:
    • kernel_build (optional);
    • Tempesta build;
    • Unit tests;
    • TLS tests;
    • python local tests;
    • python local tests with TCP segmentation 1;
    • python remote tests;
  4. Link.

It jobs works for release branch. This job just use release-x.x.x test branch if PR is created for release Tempesta branch.

(PR)Tempesta-test
  1. Tempesta branch - branch from PR (if this branch exists in Tempesta repo or master);
  2. Test branch - branch from PR merged with master;
  3. Stages:
    • kernel_build (optional);
    • Tempesta build;
    • python local tests;
    • python local tests with TCP segmentation 1;
    • python remote tests;
  4. Link.
Daily tests
  1. Tempesta branch - master;
  2. Test branch - master;
  3. Stages: as in (PR)Tempesta;
  4. Link.
Jobs with manual control

You can run tests on CI for various Tempesta and Tempesta-test branches. And also you can change tests params, MTU and remote/local setup. Link

See tempesta-ci repo for more info.

Releases

Each release (or GA), including minor versions (patch level) must be tagged, e.g.

    $ git tag
    0.5.0-pre7

Each release, e.g. 0.5.0, must have its own branch named by first two digits, e.g. 0.5. Bugfixes (i.e. versions 0.5.1, 0.5.2 etc.) must be fixated in the branches as tags.

Each release (e.g. 0.5 aka 0.5.0) and a patch of a release (e.g. 0.5.1) must be issued as a set of operating system packages.

Release procedure

Releases are issues in following steps:

  1. all the issues from current milestone are closed.
  2. the code is analyzed by Coverity scan and all the relevant reported code issues are fixed in context of a new, and the latest, issue in the milestone (please open a new issue by report of static analysis).
  3. long running tests are successfully passed on the same platform with CI.
  4. new packages are built for the current Linux kernel and Tempesta FW (Continuous delivery is described at the below).
  5. new branch and tag are created for the release.

Continuous delivery (CD)

The master branch is assumed to provide new functionality to users on a continuous basis, while release branches provide stable versions ready for usage in production.

TBD it has sense to automate building of operating system packages (release automation) for real continuous delivery and easier implementation of continuous deployment of a user side. Currently we have scripts for packages building, but the process is still manual. The packages must be automatically tested in VMs. This is the subject for Continuous delivery (#786) issue.

Users can setup their package managers, e.g. apt or dnf, to pull the pre-built packages from our servers.

Documentation

This Wiki is updated by the code developers. Please use this template when you update the wiki:


cache - H5 tag for this directive
Syntax:         cache <mode>;
Default:        cache 2;
Context:        global
Reconfig:       false
Repeat:         false

There should be additional information about the directive here. Add configuration examples for common presets or common use cases for every directive. Especially implicit directives.


This is real example for cache directive. Here:

  • Syntax - description of the directive syntax;
  • Default - value by default. This should be disabled if directive disabled by default;
  • Context - specify the scope for every directive. E.g. cache_bypass may be listed out of any directive blocks, inside vhost block and inside location block;
  • Reconfig - true | false. Specify whether this directive is on-the-fly configuration;
  • Repeat - true | false. Specify whether this directive can be used multiple times;

You can edit the wiki using the GitHub web interface or work with it as any other repo clonning it from git@github.com:tempesta-tech/tempesta.wiki.git

Syntax

We maintain the Wiki in a GitHub repository, so a GitHub Flavored Markdown extension (a.k.a. GFM)is used.

Please after commit check how the changes look on the website wiki. The website wiki is generated by the Pythom library Marko GFM and rendered with Prism. E.g. note that it has more restricted set of supported languages for code snippets. Couple of rules to follow:

  • the website wiki has it's own headers, so the top header in the wiki is ##, not #
  • to make a link to a wiki page from another one, use the page name, without any slashes or domain. E.g. [PURGE](Caching-Responses) is correctly displayed on the GitHub and website wikis, while [PURGE](/Caching-Responses) or [PURGE](https://github.com/tempesta-tech/tempesta/wiki/Caching-Responses) are broken.

Technical debt documentation

If changes made to code left place for further improvements, 'to do' mark should be left in code in format:

/* TODO #3456: Short description of planned improvements */

For the improvement should be created issue and its number should be referred in the TODO comment along with short description of it. Please do not use FIXME for that purpose, so it can be left for private use in drafts by developers.

References

  1. Continuous Integration by Martin Fowler.
  2. Continuous integration essentials by Codeship.
  3. A successful Git branching model.
Clone this wiki locally