- The version field in the config file is updated when the file system is opened with a newer CryFS version (i.e. it is migrated to the newer version).

- We introduced a CreatedWithVersion field instead which gets the semantics the version field had before (i.e. which version of CryFS was the file system originally created with)
- Move VersionCompare to gitversion package
This commit is contained in:
Sebastian Messmer 2016-03-27 00:09:07 +08:00
parent 7b5970a94e
commit b9ac810414
22 changed files with 350 additions and 146 deletions

View File

@ -3,7 +3,6 @@ project (cryfs-cli)
set(SOURCES
Cli.cpp
VersionChecker.cpp
VersionCompare.cpp
CallAfterTimeout.cpp
Environment.cpp
program_options/utils.cpp

View File

@ -21,7 +21,7 @@
#include <gitversion/gitversion.h>
#include "VersionChecker.h"
#include "VersionCompare.h"
#include <gitversion/VersionCompare.h>
#include "Environment.h"
//TODO Fails with gpg-homedir in filesystem: gpg --homedir gpg-homedir --gen-key
@ -64,6 +64,7 @@ using boost::chrono::duration_cast;
using boost::chrono::minutes;
using boost::chrono::milliseconds;
using cpputils::dynamic_pointer_move;
using gitversion::VersionCompare;
//TODO Delete a large file in parallel possible? Takes a long time right now...
//TODO Improve parallelity.

View File

@ -1,43 +0,0 @@
#include "VersionCompare.h"
using std::string;
namespace cryfs {
bool VersionCompare::isOlderThan(const string &v1, const string &v2) {
return _isOlderThanStartingFrom(v1, v2, 0, 0);
}
bool VersionCompare::_isOlderThanStartingFrom(const string &v1, const string &v2, size_t startPos1, size_t startPos2) {
if (startPos1 > v1.size() && startPos2 > v2.size()) {
// All components are equal
return false;
}
string componentStr1 = _extractComponent(v1, startPos1);
string componentStr2 = _extractComponent(v2, startPos2);
uint32_t component1 = _parseComponent(componentStr1);
uint32_t component2 = _parseComponent(componentStr2);
if (component1 == component2) {
return _isOlderThanStartingFrom(v1, v2, startPos1 + componentStr1.size() + 1, startPos2 + componentStr2.size() + 1);
}
return component1 < component2;
}
string VersionCompare::_extractComponent(const string &version, size_t startPos) {
if (startPos >= version.size()) {
return "";
}
size_t found = version.find('.', startPos);
if (found == string::npos) {
return version.substr(startPos);
}
return version.substr(startPos, found-startPos);
}
uint32_t VersionCompare::_parseComponent(const string &component) {
if (component == "" || component.substr(0, 3) == "dev") {
return 0;
}
return std::stoul(component);
}
}

View File

@ -1,19 +0,0 @@
#pragma once
#ifndef MESSMER_CRYFS_CLI_VERSIONCOMPARE_H
#define MESSMER_CRYFS_CLI_VERSIONCOMPARE_H
#include <string>
namespace cryfs {
class VersionCompare {
public:
static bool isOlderThan(const std::string &v1, const std::string &v2);
private:
static bool _isOlderThanStartingFrom(const std::string &v1, const std::string &v2, size_t startPos1, size_t startPos2);
static std::string _extractComponent(const std::string &version, size_t startPos);
static uint32_t _parseComponent(const std::string &component);
};
}
#endif

View File

@ -4,6 +4,7 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <sstream>
#include <gitversion/VersionCompare.h>
namespace bf = boost::filesystem;
@ -11,15 +12,16 @@ using boost::property_tree::ptree;
using std::string;
using std::stringstream;
using cpputils::Data;
using gitversion::VersionCompare;
namespace cryfs {
CryConfig::CryConfig()
: _rootBlob(""), _encKey(""), _cipher(""), _version(""), _blocksizeBytes(0) {
: _rootBlob(""), _encKey(""), _cipher(""), _version(""), _createdWithVersion(""), _blocksizeBytes(0) {
}
CryConfig::CryConfig(CryConfig &&rhs)
: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)), _version(std::move(rhs._version)), _blocksizeBytes(rhs._blocksizeBytes) {
: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)), _version(std::move(rhs._version)), _createdWithVersion(std::move(rhs._createdWithVersion)), _blocksizeBytes(rhs._blocksizeBytes) {
}
CryConfig CryConfig::load(const Data &data) {
@ -33,6 +35,7 @@ CryConfig CryConfig::load(const Data &data) {
cfg._encKey = pt.get("cryfs.key", "");
cfg._cipher = pt.get("cryfs.cipher", "");
cfg._version = pt.get("cryfs.version", "0.8"); // CryFS 0.8 didn't specify this field, so if the field doesn't exist, it's 0.8.
cfg._createdWithVersion = pt.get("cryfs.createdWithVersion", cfg._version); // In Crfys <= 0.9.2, we didn't have this field, but also didn't update cryfs.version, so we can use this field instead.
cfg._blocksizeBytes = pt.get<uint64_t>("cryfs.blocksizeBytes", 32832); // CryFS <= 0.9.2 used a 32KB block size which was this physical block size.
return cfg;
}
@ -44,6 +47,7 @@ Data CryConfig::save() const {
pt.put("cryfs.key", _encKey);
pt.put("cryfs.cipher", _cipher);
pt.put("cryfs.version", _version);
pt.put("cryfs.createdWithVersion", _createdWithVersion);
pt.put<uint64_t>("cryfs.blocksizeBytes", _blocksizeBytes);
stringstream stream;
@ -83,6 +87,14 @@ void CryConfig::SetVersion(const std::string &value) {
_version = value;
}
const std::string &CryConfig::CreatedWithVersion() const {
return _createdWithVersion;
}
void CryConfig::SetCreatedWithVersion(const std::string &value) {
_createdWithVersion = value;
}
uint64_t CryConfig::BlocksizeBytes() const {
return _blocksizeBytes;
}

View File

@ -27,6 +27,9 @@ public:
const std::string &Version() const;
void SetVersion(const std::string &value);
const std::string &CreatedWithVersion() const;
void SetCreatedWithVersion(const std::string &value);
uint64_t BlocksizeBytes() const;
void SetBlocksizeBytes(uint64_t value);
@ -38,6 +41,7 @@ private:
std::string _encKey;
std::string _cipher;
std::string _version;
std::string _createdWithVersion;
uint64_t _blocksizeBytes;
DISALLOW_COPY_AND_ASSIGN(CryConfig);

View File

@ -21,6 +21,7 @@ namespace cryfs {
CryConfig config;
config.SetCipher(_generateCipher(cipherFromCommandLine));
config.SetVersion(gitversion::VersionString());
config.SetCreatedWithVersion(gitversion::VersionString());
config.SetBlocksizeBytes(_generateBlocksizeBytes(blocksizeBytesFromCommandLine));
config.SetRootBlob(_generateRootBlobKey());
config.SetEncryptionKey(_generateEncKey(config.Cipher()));

View File

@ -40,6 +40,10 @@ optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
}
std::cout << "done" << std::endl;
_checkVersion(*config->config());
if (config->config()->Version() != gitversion::VersionString()) {
config->config()->SetVersion(gitversion::VersionString());
config->save();
}
_checkCipher(*config->config());
return std::move(*config);
}

View File

@ -3,7 +3,14 @@ project (gitversion)
include(gitversion.cmake)
get_git_version(GIT_VERSION)
add_library(${PROJECT_NAME} STATIC gitversion.cpp versionstring.cpp parser.cpp)
set(SOURCES
gitversion.cpp
versionstring.cpp
parser.cpp
VersionCompare.cpp
)
add_library(${PROJECT_NAME} STATIC ${SOURCES})
target_link_libraries(${PROJECT_NAME})
target_compile_definitions(${PROJECT_NAME} PRIVATE GIT_VERSION_STRING="${GIT_VERSION}")
target_add_boost(${PROJECT_NAME})

View File

@ -0,0 +1,27 @@
#include "VersionCompare.h"
#include "parser.h"
#include <tuple>
#include <cstring>
using std::string;
namespace gitversion {
bool VersionCompare::isOlderThan(const string &v1Str, const string &v2Str) {
VersionInfo v1 = Parser::parse(v1Str);
VersionInfo v2 = Parser::parse(v2Str);
unsigned long v1_major = std::stoul(v1.majorVersion);
unsigned long v2_major = std::stoul(v2.majorVersion);
unsigned long v1_minor = std::stoul(v1.minorVersion);
unsigned long v2_minor = std::stoul(v2.minorVersion);
unsigned long v1_hotfix = std::stoul(v1.hotfixVersion);
unsigned long v2_hotfix = std::stoul(v2.hotfixVersion);
int versionTagCompare = strcmp(v1.versionTag.c_str(), v2.versionTag.c_str());
return (v1_major < v2_major) || ((v1_major == v2_major) && (
(v1_minor < v2_minor) || ((v1_minor == v2_minor) && (
(v1_hotfix < v2_hotfix) || ((v1_hotfix == v2_hotfix) && (
(0 > versionTagCompare) || ((0 == versionTagCompare) && (
(v1.commitsSinceTag < v2.commitsSinceTag)
))))))));
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#ifndef GITVERSION_VERSIONCOMPARE_H
#define GITVERSION_VERSIONCOMPARE_H
#include <string>
namespace gitversion {
class VersionCompare {
public:
static bool isOlderThan(const std::string &v1, const std::string &v2);
};
}
#endif

View File

@ -16,22 +16,23 @@ namespace gitversion {
VersionInfo result;
string versionNumber;
optional<string> versionInfo;
tie(versionNumber, versionInfo) = _splitAtPlusSign(versionString);
tie(result.majorVersion, result.minorVersion, result.versionTag) = _extractMajorMinorTag(versionNumber);
tie(versionNumber, versionInfo) = _splitAt(versionString, '+');
tie(result.majorVersion, result.minorVersion, result.hotfixVersion, result.versionTag) = _extractMajorMinorHotfixTag(versionNumber);
result.isDevVersion = (versionInfo != none);
result.isStableVersion = !result.isDevVersion && (result.versionTag == "" || result.versionTag == "stable");
if (versionInfo != none && *versionInfo != "unknown") {
result.gitCommitId = _extractGitCommitId(*versionInfo);
tie(result.gitCommitId, result.commitsSinceTag) = _extractGitCommitIdAndCommitsSinceTag(*versionInfo);
} else {
result.gitCommitId = "";
result.commitsSinceTag = 0;
}
return result;
}
pair<string, optional<string>> Parser::_splitAtPlusSign(const string &versionString) {
pair<string, optional<string>> Parser::_splitAt(const string &versionString, char delimiter) {
istringstream stream(versionString);
string versionNumber;
getline(stream, versionNumber, '+');
getline(stream, versionNumber, delimiter);
if (!stream.good()) {
return std::make_pair(versionNumber, none);
} else {
@ -39,11 +40,23 @@ namespace gitversion {
getline(stream, versionInfo);
return std::make_pair(versionNumber, versionInfo);
}
};
}
tuple<string, string, string> Parser::_extractMajorMinorTag(const string &versionNumber) {
tuple<string, string, string, string> Parser::_extractMajorMinorHotfixTag(const string &versionNumber) {
string majorMinorHotfix;
optional<string> versionTag;
tie(majorMinorHotfix, versionTag) = _splitAt(versionNumber, '-');
string major, minor, hotfix;
tie(major, minor, hotfix) = _extractMajorMinorHotfix(majorMinorHotfix);
if (versionTag == none) {
versionTag = "";
}
return std::make_tuple(major, minor, hotfix, *versionTag);
}
tuple<string, string, string> Parser::_extractMajorMinorHotfix(const string &versionNumber) {
istringstream stream(versionNumber);
string major, minor, hotfix, tag;
string major, minor, hotfix;
getline(stream, major, '.');
if (!stream.good()) {
minor = "0";
@ -53,17 +66,12 @@ namespace gitversion {
if (!stream.good()) {
hotfix = "0";
} else {
getline(stream, hotfix, '-');
getline(stream, hotfix);
}
if (!stream.good()) {
tag = "";
} else {
getline(stream, tag);
}
return std::make_tuple(major, minor, tag);
return std::make_tuple(major, minor, hotfix);
};
string Parser::_extractGitCommitId(const string &versionInfo) {
std::tuple<string, unsigned long> Parser::_extractGitCommitIdAndCommitsSinceTag(const string &versionInfo) {
istringstream stream(versionInfo);
string commitsSinceTag;
getline(stream, commitsSinceTag, '.');
@ -75,7 +83,7 @@ namespace gitversion {
if (gitCommitId[0] != 'g') {
throw std::logic_error("Invalid version information: Git commit id component doesn't start with 'g'.");
}
return gitCommitId.substr(1);
return std::make_tuple(gitCommitId.substr(1), std::stoul(commitsSinceTag));
}
}

View File

@ -14,6 +14,8 @@ namespace gitversion {
std::string gitCommitId;
std::string majorVersion;
std::string minorVersion;
std::string hotfixVersion;
unsigned int commitsSinceTag;
};
class Parser final {
@ -21,9 +23,10 @@ namespace gitversion {
static VersionInfo parse(const std::string &versionString);
private:
static std::pair<std::string, boost::optional<std::string>> _splitAtPlusSign(const std::string &versionString);
static std::tuple<std::string, std::string, std::string> _extractMajorMinorTag(const std::string &versionNumber);
static std::string _extractGitCommitId(const std::string &versionInfo);
static std::pair<std::string, boost::optional<std::string>> _splitAt(const std::string &versionString, char delimiter);
static std::tuple<std::string, std::string, std::string, std::string> _extractMajorMinorHotfixTag(const std::string &versionNumber);
static std::tuple<std::string, std::string, std::string> _extractMajorMinorHotfix(const std::string &versionNumber);
static std::tuple<std::string, unsigned long> _extractGitCommitIdAndCommitsSinceTag(const std::string &versionInfo);
};
}

View File

@ -11,7 +11,6 @@ set(SOURCES
CliTest_ShowingHelp.cpp
EnvironmentTest.cpp
VersionCheckerTest.cpp
VersionCompareTest.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})

View File

@ -1,54 +0,0 @@
#include <gtest/gtest.h>
#include <cryfs-cli/VersionCompare.h>
using namespace cryfs;
using std::string;
class VersionCompareTest : public ::testing::Test {
public:
void EXPECT_IS_OLDER_THAN(const string &v1, const string &v2) {
EXPECT_TRUE(VersionCompare::isOlderThan(v1, v2));
EXPECT_FALSE(VersionCompare::isOlderThan(v2, v1));
}
void EXPECT_IS_SAME_AGE(const string &v1, const string &v2) {
EXPECT_FALSE(VersionCompare::isOlderThan(v1, v2));
EXPECT_FALSE(VersionCompare::isOlderThan(v2, v1));
}
};
TEST_F(VersionCompareTest, IsDifferentVersion) {
EXPECT_IS_OLDER_THAN("0.8", "0.8.1");
EXPECT_IS_OLDER_THAN("0.8", "1.0");
EXPECT_IS_OLDER_THAN("0.8", "1.0.1");
EXPECT_IS_OLDER_THAN("0.8.1", "1.0");
EXPECT_IS_OLDER_THAN("0.7.9", "0.8.0");
EXPECT_IS_OLDER_THAN("1.0.0", "1.0.1");
EXPECT_IS_OLDER_THAN("1.0.0.0", "1.0.0.1");
EXPECT_IS_OLDER_THAN("1", "1.0.0.1");
EXPECT_IS_OLDER_THAN("1.0.0.0", "1.1");
}
TEST_F(VersionCompareTest, IsSameVersion) {
EXPECT_IS_SAME_AGE("0.8", "0.8");
EXPECT_IS_SAME_AGE("1.0", "1.0");
EXPECT_IS_SAME_AGE("1", "1.0");
EXPECT_IS_SAME_AGE("1.0.0", "1.0.0");
EXPECT_IS_SAME_AGE("0.8", "0.8.0");
EXPECT_IS_SAME_AGE("1", "1.0.0.0");
}
TEST_F(VersionCompareTest, ZeroPrefix) {
EXPECT_IS_OLDER_THAN("1.00.0", "1.0.01");
EXPECT_IS_SAME_AGE("1.0.01", "1.0.1");
EXPECT_IS_SAME_AGE("01.0.01", "1.0.1");
}
TEST_F(VersionCompareTest, DevVersions) {
EXPECT_IS_OLDER_THAN("0.8", "0.8.1.dev1");
EXPECT_IS_OLDER_THAN("0.8.1", "0.8.2.dev2");
EXPECT_IS_OLDER_THAN("0.8.1.dev1", "0.8.2");
EXPECT_IS_OLDER_THAN("0.8.dev1", "0.8.1");
EXPECT_IS_OLDER_THAN("0.8.dev1", "0.9");
EXPECT_IS_SAME_AGE("0.9.1.dev5", "0.9.1");
}

View File

@ -4,6 +4,7 @@
#include <cryfs/config/CryCipher.h>
#include <cpp-utils/crypto/symmetric/ciphers.h>
#include "../testutils/MockConsole.h"
#include <gitversion/gitversion.h>
using namespace cryfs;
@ -140,4 +141,14 @@ TEST_F(CryConfigCreatorTest, DoesNotAskForAnythingIfEverythingIsSpecified) {
CryConfig config = noninteractiveCreator.create(string("aes-256-gcm"), 10*1024u);
}
TEST_F(CryConfigCreatorTest, SetsCorrectCreatedWithVersion) {
CryConfig config = noninteractiveCreator.create(none, none);
EXPECT_EQ(gitversion::VersionString(), config.CreatedWithVersion());
}
TEST_F(CryConfigCreatorTest, SetsCorrectVersion) {
CryConfig config = noninteractiveCreator.create(none, none);
EXPECT_EQ(gitversion::VersionString(), config.Version());
}
//TODO Add test cases ensuring that the values entered are correctly taken

View File

@ -126,6 +126,48 @@ TEST_F(CryConfigFileTest, Cipher_SaveAndLoad) {
EXPECT_EQ("twofish-128-cfb", loaded.config()->Cipher());
}
TEST_F(CryConfigFileTest, Version_Init) {
CryConfigFile created = CreateAndLoadEmpty();
EXPECT_EQ("", created.config()->Version());
}
TEST_F(CryConfigFileTest, Version_CreateAndLoad) {
CryConfig cfg = Config();
cfg.SetVersion("0.9.2");
Create(std::move(cfg));
CryConfigFile loaded = Load().value();
EXPECT_EQ("0.9.2", loaded.config()->Version());
}
TEST_F(CryConfigFileTest, Version_SaveAndLoad) {
CryConfigFile created = CreateAndLoadEmpty();
created.config()->SetVersion("0.9.2");
created.save();
CryConfigFile loaded = Load().value();
EXPECT_EQ("0.9.2", loaded.config()->Version());
}
TEST_F(CryConfigFileTest, CreatedWithVersion_Init) {
CryConfigFile created = CreateAndLoadEmpty();
EXPECT_EQ("", created.config()->Version());
}
TEST_F(CryConfigFileTest, CreatedWithVersion_CreateAndLoad) {
CryConfig cfg = Config();
cfg.SetCreatedWithVersion("0.9.2");
Create(std::move(cfg));
CryConfigFile loaded = Load().value();
EXPECT_EQ("0.9.2", loaded.config()->CreatedWithVersion());
}
TEST_F(CryConfigFileTest, CreatedWithVersion_SaveAndLoad) {
CryConfigFile created = CreateAndLoadEmpty();
created.config()->SetCreatedWithVersion("0.9.2");
created.save();
CryConfigFile loaded = Load().value();
EXPECT_EQ("0.9.2", loaded.config()->CreatedWithVersion());
}
//Test that the encrypted config file has the same size, no matter how big the plaintext config data.
TEST_F(CryConfigFileTest, ConfigFileHasFixedSize) {
TempFile file1(false);

View File

@ -4,6 +4,7 @@
#include <cpp-utils/tempfile/TempFile.h>
#include <cpp-utils/random/Random.h>
#include <cpp-utils/crypto/symmetric/ciphers.h>
#include <gitversion/gitversion.h>
using cpputils::unique_ref;
using cpputils::make_unique_ref;
@ -63,6 +64,13 @@ public:
cfg.save();
}
void CreateWithVersion(const string &version, const string &password = "mypassword") {
auto cfg = loader(password, false).loadOrCreate(file.path()).value();
cfg.config()->SetVersion(version);
cfg.config()->SetCreatedWithVersion(version);
cfg.save();
}
TempFile file;
};
@ -147,3 +155,24 @@ TEST_F(CryConfigLoaderTest, Cipher_Create) {
//aes-256-gcm is the default cipher chosen by mockConsole()
EXPECT_EQ("aes-256-gcm", created.config()->Cipher());
}
TEST_F(CryConfigLoaderTest, Version_Load) {
CreateWithVersion("0.9.2");
auto loaded = Load().value();
EXPECT_EQ(gitversion::VersionString(), loaded.config()->Version());
EXPECT_EQ("0.9.2", loaded.config()->CreatedWithVersion());
}
TEST_F(CryConfigLoaderTest, Version_Load_IsStoredAndNotOnlyOverwrittenInMemoryOnLoad) {
CreateWithVersion("0.9.2", "mypassword");
Load().value();
auto configFile = CryConfigFile::load(file.path(), "mypassword").value();
EXPECT_EQ(gitversion::VersionString(), configFile.config()->Version());
EXPECT_EQ("0.9.2", configFile.config()->CreatedWithVersion());
}
TEST_F(CryConfigLoaderTest, Version_Create) {
auto created = Create();
EXPECT_EQ(gitversion::VersionString(), created.config()->Version());
EXPECT_EQ(gitversion::VersionString(), created.config()->CreatedWithVersion());
}

View File

@ -87,15 +87,36 @@ TEST_F(CryConfigTest, Version) {
}
TEST_F(CryConfigTest, Version_AfterMove) {
cfg.SetCipher("0.9.1");
cfg.SetVersion("0.9.1");
CryConfig moved = std::move(cfg);
EXPECT_EQ("0.9.1", moved.Cipher());
EXPECT_EQ("0.9.1", moved.Version());
}
TEST_F(CryConfigTest, Version_AfterSaveAndLoad) {
cfg.SetCipher("0.9.2");
cfg.SetVersion("0.9.2");
CryConfig loaded = SaveAndLoad(std::move(cfg));
EXPECT_EQ("0.9.2", loaded.Cipher());
EXPECT_EQ("0.9.2", loaded.Version());
}
TEST_F(CryConfigTest, CreatedWithVersion_Init) {
EXPECT_EQ("", cfg.CreatedWithVersion());
}
TEST_F(CryConfigTest, CreatedWithVersion) {
cfg.SetCreatedWithVersion("0.9.3");
EXPECT_EQ("0.9.3", cfg.CreatedWithVersion());
}
TEST_F(CryConfigTest, CreatedWithVersion_AfterMove) {
cfg.SetCreatedWithVersion("0.9.3");
CryConfig moved = std::move(cfg);
EXPECT_EQ("0.9.3", moved.CreatedWithVersion());
}
TEST_F(CryConfigTest, CreatedWithVersion_AfterSaveAndLoad) {
cfg.SetCreatedWithVersion("0.9.3");
CryConfig loaded = SaveAndLoad(std::move(cfg));
EXPECT_EQ("0.9.3", loaded.CreatedWithVersion());
}
TEST_F(CryConfigTest, BlocksizeBytes_Init) {
@ -115,6 +136,7 @@ TEST_F(CryConfigTest, BlocksizeBytes_AfterMove) {
TEST_F(CryConfigTest, BlocksizeBytes_AfterSaveAndLoad) {
cfg.SetBlocksizeBytes(10*1024);
cfg.SetVersion("0.9.3"); // This is a workaround, because we overwrite ths blocksizeBytes config value for versions smaller than 0.9.3
CryConfig loaded = SaveAndLoad(std::move(cfg));
EXPECT_EQ(10*1024u, loaded.BlocksizeBytes());
}

View File

@ -2,6 +2,7 @@ project (gitversion-test)
set(SOURCES
ParserTest.cpp
VersionCompareTest.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})

View File

@ -7,50 +7,60 @@ TEST(ParserTest, TestUnknownVersion) {
VersionInfo info = Parser::parse("0+unknown");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("0", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestReleaseVersion_1) {
VersionInfo info = Parser::parse("0.9.2");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("2", info.hotfixVersion);
EXPECT_FALSE( info.isDevVersion);
EXPECT_TRUE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestReleaseVersion_2) {
VersionInfo info = Parser::parse("1.02.3");
EXPECT_EQ("1", info.majorVersion);
EXPECT_EQ("02", info.minorVersion);
EXPECT_EQ("3", info.hotfixVersion);
EXPECT_FALSE( info.isDevVersion);
EXPECT_TRUE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestReleaseVersion_3) {
VersionInfo info = Parser::parse("01.020.3");
EXPECT_EQ("01", info.majorVersion);
EXPECT_EQ("020", info.minorVersion);
EXPECT_EQ("3", info.hotfixVersion);
EXPECT_FALSE( info.isDevVersion);
EXPECT_TRUE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyReleaseVersion) {
VersionInfo info = Parser::parse("0.9.0+0.g5753e4f.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("5753e4f", info.gitCommitId);
EXPECT_EQ("", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
@ -58,138 +68,190 @@ TEST(ParserTest, TestDevVersion) {
VersionInfo info = Parser::parse("0.9.0+2.g0123abcdef");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("", info.versionTag);
EXPECT_EQ(2u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyDevVersion) {
VersionInfo info = Parser::parse("0.9.0+20.g0123abcdef.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("", info.versionTag);
EXPECT_EQ(20u, info.commitsSinceTag);
}
TEST(ParserTest, TestReleaseVersion_StableTag) {
VersionInfo info = Parser::parse("0.9.2-stable");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("2", info.hotfixVersion);
EXPECT_FALSE( info.isDevVersion);
EXPECT_TRUE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("stable", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyReleaseVersion_StableTag) {
VersionInfo info = Parser::parse("0.9.0-stable+0.g5753e4f.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("5753e4f", info.gitCommitId);
EXPECT_EQ("stable", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestDevVersion_StableTag) {
VersionInfo info = Parser::parse("0.9.0-stable+2.g0123abcdef");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("stable", info.versionTag);
EXPECT_EQ(2u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyDevVersion_StableTag) {
VersionInfo info = Parser::parse("0.9.0-stable+20.g0123abcdef.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("stable", info.versionTag);
EXPECT_EQ(20u, info.commitsSinceTag);
}
TEST(ParserTest, TestReleaseVersion_AlphaTag) {
VersionInfo info = Parser::parse("0.9.2-alpha");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("2", info.hotfixVersion);
EXPECT_FALSE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("alpha", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyReleaseVersion_AlphaTag) {
VersionInfo info = Parser::parse("0.9.0-alpha+0.g5753e4f.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("5753e4f", info.gitCommitId);
EXPECT_EQ("alpha", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestDevVersion_AlphaTag) {
VersionInfo info = Parser::parse("0.9.0-alpha+2.g0123abcdef");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("alpha", info.versionTag);
EXPECT_EQ(2u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyDevVersion_AlphaTag) {
VersionInfo info = Parser::parse("0.9.0-alpha+20.g0123abcdef.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("alpha", info.versionTag);
EXPECT_EQ(20u, info.commitsSinceTag);
}
TEST(ParserTest, TestReleaseVersion_WithoutHotfixVersion) {
VersionInfo info = Parser::parse("1.0-beta");
EXPECT_EQ("1", info.majorVersion);
EXPECT_EQ("0", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_FALSE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("beta", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestReleaseVersion_RCTag) {
VersionInfo info = Parser::parse("0.9.2-rc1");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("2", info.hotfixVersion);
EXPECT_FALSE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("", info.gitCommitId);
EXPECT_EQ("rc1", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyReleaseVersion_RCTag) {
VersionInfo info = Parser::parse("0.9.0-rc1+0.g5753e4f.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("5753e4f", info.gitCommitId);
EXPECT_EQ("rc1", info.versionTag);
EXPECT_EQ(0u, info.commitsSinceTag);
}
TEST(ParserTest, TestDevVersion_RCTag) {
VersionInfo info = Parser::parse("0.9.0-rc1+2.g0123abcdef");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("rc1", info.versionTag);
EXPECT_EQ(2u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyDevVersion_RCTag) {
VersionInfo info = Parser::parse("0.9.0-rc1+20.g0123abcdef.dirty");
EXPECT_EQ("0", info.majorVersion);
EXPECT_EQ("9", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("rc1", info.versionTag);
EXPECT_EQ(20u, info.commitsSinceTag);
}
TEST(ParserTest, TestDirtyDevVersion_WithoutMinorVersion) {
VersionInfo info = Parser::parse("1-rc1+20.g0123abcdef.dirty");
EXPECT_EQ("1", info.majorVersion);
EXPECT_EQ("0", info.minorVersion);
EXPECT_EQ("0", info.hotfixVersion);
EXPECT_TRUE( info.isDevVersion);
EXPECT_FALSE( info.isStableVersion);
EXPECT_EQ("0123abcdef", info.gitCommitId);
EXPECT_EQ("rc1", info.versionTag);
EXPECT_EQ(20u, info.commitsSinceTag);
}

View File

@ -0,0 +1,74 @@
#include <gtest/gtest.h>
#include <gitversion/VersionCompare.h>
using namespace gitversion;
using std::string;
class VersionCompareTest : public ::testing::Test {
public:
void EXPECT_IS_OLDER_THAN(const string &v1, const string &v2) {
EXPECT_TRUE(VersionCompare::isOlderThan(v1, v2));
EXPECT_FALSE(VersionCompare::isOlderThan(v2, v1));
}
void EXPECT_IS_SAME_AGE(const string &v1, const string &v2) {
EXPECT_FALSE(VersionCompare::isOlderThan(v1, v2));
EXPECT_FALSE(VersionCompare::isOlderThan(v2, v1));
}
};
TEST_F(VersionCompareTest, IsDifferentVersion) {
EXPECT_IS_OLDER_THAN("0.8", "0.8.1");
EXPECT_IS_OLDER_THAN("0.8", "1.0");
EXPECT_IS_OLDER_THAN("0.8", "1.0.1");
EXPECT_IS_OLDER_THAN("0.8.1", "1.0");
EXPECT_IS_OLDER_THAN("0.7.9", "0.8.0");
EXPECT_IS_OLDER_THAN("1.0.0", "1.0.1");
EXPECT_IS_OLDER_THAN("1", "1.0.1");
EXPECT_IS_OLDER_THAN("1.0.0", "1.1");
}
TEST_F(VersionCompareTest, IsSameVersion) {
EXPECT_IS_SAME_AGE("0.8", "0.8");
EXPECT_IS_SAME_AGE("1.0", "1.0");
EXPECT_IS_SAME_AGE("1", "1.0");
EXPECT_IS_SAME_AGE("1.0.0", "1.0.0");
EXPECT_IS_SAME_AGE("0.8", "0.8.0");
EXPECT_IS_SAME_AGE("1", "1.0.0.0");
}
TEST_F(VersionCompareTest, ZeroPrefix) {
EXPECT_IS_OLDER_THAN("1.00.0", "1.0.01");
EXPECT_IS_SAME_AGE("1.0.01", "1.0.1");
EXPECT_IS_SAME_AGE("01.0.01", "1.0.1");
}
TEST_F(VersionCompareTest, VersionTags) {
EXPECT_IS_OLDER_THAN("0.9.3-alpha", "0.9.3-beta");
EXPECT_IS_OLDER_THAN("1.0-beta", "1.0-rc1");
EXPECT_IS_OLDER_THAN("1.0-rc1", "1.0-rc2");
EXPECT_IS_OLDER_THAN("1.0-rc2", "1.0-stable");
EXPECT_IS_SAME_AGE("0.9.3-alpha", "0.9.3-alpha");
EXPECT_IS_SAME_AGE("1-beta", "1-beta");
EXPECT_IS_SAME_AGE("0.9.3-rc1", "0.9.3-rc1");
}
TEST_F(VersionCompareTest, DevVersions) {
EXPECT_IS_OLDER_THAN("0.8", "0.8.1+1.g1234");
EXPECT_IS_OLDER_THAN("0.8.1", "0.8.2+1.g1234");
EXPECT_IS_OLDER_THAN("0.8.1+1.g1234", "0.8.2");
EXPECT_IS_OLDER_THAN("0.8+1.g1234", "0.8.1");
EXPECT_IS_OLDER_THAN("0.8+1.g1234", "0.9");
EXPECT_IS_OLDER_THAN("0.9+1.g1234", "0.9+2.g1234");
EXPECT_IS_SAME_AGE("0.9.1+1.g1234", "0.9.1+1.g3456");
EXPECT_IS_SAME_AGE("0.9.1+5.g1234", "0.9.1+5.g2345.dirty");
}
TEST_F(VersionCompareTest, DevVersions_VersionTags) {
EXPECT_IS_OLDER_THAN("0.9.3-alpha+3.gabcd", "0.9.3-alpha+4.gabcd");
EXPECT_IS_OLDER_THAN("0.9.3-alpha+5.gabcd", "0.9.3-beta");
EXPECT_IS_OLDER_THAN("0.9.3-alpha+5.gabcd", "0.9.3-beta+1.gabcd");
EXPECT_IS_OLDER_THAN("0.9.3-alpha+5.gabcd", "1+0.gabcd.dirty");
EXPECT_IS_OLDER_THAN("0.9.3-alpha+5.gabcd", "1");
EXPECT_IS_SAME_AGE("0.9.3-alpha+3.gabcd", "0.9.3-alpha+3.gabcd");
}