Become one of the contributors! We thrive to build a welcoming and open community for anyone who wants to use Mongoose or contribute to it. Here we describe how to contribute to any of the {code} projects.
Please, note that all contributors shall follow the Contributor Agreement guidelines provided here.
- Contributors
1.2. Roles - Versions
2.1. Backward Compatibility
2.2. Numbers - Issues
3.1. States
3.2. Defects Priority
3.3. Specific Properties - Continuous Integration
4.1. Build
4.2. Testing
4.2.1. Unit Tests
4.2.2. Integration Tests
4.2.3. Legacy System Tests
4.2.3.1. Containerized Tests
4.2.4. Endurance Tests
4.2.5. Robot Tests
4.3. Releasing - Code
5.1. Style
5.2. Exception Handling
5.3. Performance
Alphabetically:
- Andrey Kurilov
- Gennady Eremeev
- Ilya Kisliakovsky
- Kirill Gusakov
- Mikhail Danilov
- Mikhail Malygin
- Olga Zhavzharova
- Veronika Kochugova
Name | Responsibilities | Current Assignees |
---|---|---|
User | Report the issues | Definitely unknown |
Developer |
|
|
Owner |
|
|
The following interfaces are mentioned as the subject of the backward compatibility:
- Input (item list files, scenario files, configuration options)
- Output files containing the metrics
- API
Mongoose uses the semantic versioning. This means that the X.Y.Z version notation is used:
- X
Major version number. Points to significant design and interfaces change. The backward compatibility is not guaranteed. - Y
Minor version number. The backward compatibility is guaranteed. - Z
Patch version number. Includes only the defect fixes.
Types:
- Defect
- Story
- Task
- Sub-task
Type | Description |
---|---|
Defect | The defect/bug which affects the released version (the type "Task" should be used if a defect/bug affects the version which is not released yet) |
Story | High-level use case or a long-term activity aspect (testing, performance, etc) |
Task | A task which couldn't be included into any defect/story |
Sub-task | A task which could be included into a defect/story |
Tracker link: https://mongoose-issues.atlassian.net/projects/GOOSE
State | Description |
---|---|
OPEN | All new issues should have this state. The issues are selected from the set of the OPEN issues for the proposal and review process. The task is updated w/ the corresponding comment but left in the OPEN state if it's considered incomplete/incorrect. Also incomplete/incorrect issue should be assigned back to the reporter. |
PROPOSED | The issue is selected for the approval by the owners. |
DEFERRED | Owners have approved the issue to be processed after the next major/minor (non-patch) version is released. |
ACCEPTED | Owners approved the issue to be processed before the next major/minor (non-patch) version is released. |
ESCALATED | Critical defect which interrupts all DEFERRED/ACCEPTED issues processing. Causes the new patch version release ASAP. |
IN PROGRESS | The issue is in progress currently either initially done and the corresponding merge request to the master branch is created |
RESOLVED | Issue is done and the corresponding changes are merged into the master branch |
CLOSED | The new version is released containing the corresponding changes |
Note:
The corresponding impact probability/frequency is not taken into account in the process currently. For example, all defects are assumed to be equally frequently occurring and affecting same users, regardless the particular scenario/use case. This approach is used due to the lack of the sufficient statistical information about the Mongoose usage.
Priority | Conditions | Target state as a result of the review |
---|---|---|
Critical | No workaround available and any of the following:
|
ESCALATED |
Non-critical | Not critical and not minor | ACCEPTED (for the next minor/major version) |
Minor | Any of the following:
|
OPEN or ACCEPTED |
Name | Applicable Issue Types | Who is responsible to specify | Notes |
---|---|---|---|
Affected version | Defect | Reporter: user/developer/owner | Only the latest version may be used for the defect reporting. The issue should be rejected if the reported version is not latest. |
Branch | Defect, Task, Sub-task | Reviewer: developer/owner | |
Description | Task, Sub-task | Reporter: user/developer/owner | |
Expected behaviour | Defect | Reporter: user/developer/owner | The reference to the particular documentation part describing the expected behavior is preferable. |
Fix version | Defect, Task, Sub-task | Reviewer: developer/owner | |
Limitations | Story | Reviewer: developer/owner | |
Observed behaviour | Defect | Reporter: user/developer/owner | Error message, errors.log output file, etc. |
Pull request | Defect, Task, Sub-task | Reviewer: developer/owner | |
Resolution commit | Defect, Task, Sub-task | Reviewer: developer/owner | |
Root cause | Defect | Reviewer: developer/owner | |
Start command/request | Defect | Reporter: user/developer/owner | Leave only the essential things to reproduce: try to check if possible if the bug is reproducible w/o distributed mode, different concurrency level, item data size, etc. |
Scenario | Defect | Reporter: user/developer/owner | Don't clutter with large scenario files. Simplify the scenario leaving only the essential things. |
Steps | Defect | Reporter: user/developer/owner | |
Purpose | Story | Reporter: user/developer/owner | Which particular problem should be solved with Mongoose? The links to the related documents and literature are encouraged. |
Requirements | Story | Reporter: user/developer/owner | Both functional and performance requirements are mandatory. Optionally the additional requirements/possible enhancements may be specified. |
https://gitlab.com/emcmongoose/mongoose/pipelines for Windows: https://ci.appveyor.com/project/veronikaKochugova/mongoose
Mongoose may be distributed as a single jar. JDK 11+ is required to build.
./gradlew clean jar
The resulting jar file path is ./build/libs/mongoose-<VERSION>.jar
.
./gradlew clean test
./gradlew clean integrationTest
The system tests use the JUnit parameterization. The parameter values are taken from the environment. The list of the system tests parameters below:
Parameter Name | Acceptable Values | Values Meaning |
---|---|---|
STORAGE_TYPE | s3, atmos, fs, swift | (the same) |
RUN_MODE | local, distributed | 1, 2 |
CONCURRENCY | unlimited, single, small, medium, high | 0, 1, 10, 100, 1000 |
ITEM_SIZE | empty, small, medium, large, huge | 0, 10KB, 1MB, 100MB, 10GB |
To run the system tests for the particular case use the commands like below:
export MONGOOSE_IMAGE_VERSION=testing
export STORAGE_TYPE=s3
export RUN_MODE=distributed
export CONCURRENCY=medium
export ITEM_SIZE=small
./gradlew clean systemTest --tests com.emc.mongoose.system.CircularAppendTest
Note that some system tests will not run for some parameter values. The acceptable parameter values are declared explicitly in the .travis.yml
file.
Since v4.0.0 all system tests are containerized. To run a system test locally it's necessary to prepare testing Docker image manually:
./gradlew buildImage
Also it's necessary to supply the testing image version to the system
test via environment variable MONGOOSE_IMAGE_VERSION
:
export MONGOOSE_IMAGE_VERSION=testing
export STORAGE_TYPE=atmos
export RUN_MODE=distributed
export CONCURRENCY=medium
export ITEM_SIZE=small
./gradlew clean systemTest --tests com.emc.mongoose.system.CreateNoLimitTest
export MONGOOSE_IMAGE_VERSION=testing
export STORAGE_TYPE=swift
export RUN_MODE=distributed
export CONCURRENCY=unlimited
export ITEM_SIZE=large
./gradlew clean enduranceTest --tests com.emc.mongoose.endurance.ParallelPipelineAndInfiniteLoopTest
Note:
Currently the Robot tests are failing when being executed locally and passing when being executed on the Gitlab CI
export SUITE=<SUITE>
export TEST=<TEST>
./gradlew robotest
Example:
SUITE=api.storage TEST=s3 ./gradlew clean robotest
- Ensure all tests are OK
- Ensure the new version documentation is ready
- Share the testing build with QE and repeat this step until the qualification is OK
- Create/replace the corresponding VCS tags:
git tag -d latest git push origin :refs/tags/latest git tag -a latest -m latest git push --tags --force
- Merge to the
release
branch - Update the projects depending on the Mongoose's API (storage drivers, at least)
Google Java Style is used as default.
Git autoformatting hook reformats Java source code to comply with Google Java Style.
The hook script is in the root of the repository named pre-commit
.pre-commit
MUST be copied to the directory .git/hooks/
and you need to check that the script has the access permissions to execute:
ls -l pre-commit
If not, assign permissions for execution:
chmod +x pre-commit
This hook will work automatically with any commit and format the code in the same style.
- If interface is named
Foo
then:- Abstract implementation should be named as
FooBase
- Default concrete implementation should be names as
FooImpl
- Abstract implementation should be named as
- Any field/local variable should be final if possible
The threads are not used in the usual way (fibers are used instead for the multitasking purposes). Therefore, having
an InterruptedException
thrown means that the run was interrupted externally. To stop the run, it's necessary to pass
the exception to the uppermost level of the call stack. However, the InterruptedException
is a checked
exception and usually couldn't be passed outward. The utility method
com.github.akurilov.commons.lang.Exceptions#throwUnchecked
should be used for this:
...
import static com.github.akurilov.commons.lang.Exceptions.throwUnchecked;
...
try {
foo(); // may throw an InterruptedException
} catch(final InterruptedException e) {
throwUnchecked(e);
}
The following exceptions catching should be avoided as far as the InterruptedException
may be swallowed occasionally:
Throwable
Exception
Take care about the performance in the critical places:
- Avoid frequent objects instantiation
- Avoid unnecessary frequent allocation
- Avoid frequent method calls if possible
- Avoid deep call stack if possible
- Avoid I/O threads blocking
- Avoid anonymous classes in the time-critical code
- Avoid non-static inner classes in the time-critical code
- Use thread locals (encryption, string builders)
- Use buffering, buffer everything
- Use batch processing if possible