blob: a74069d34fe62339b14cbb6bd7fe6610ae5945f6 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "kudu/util/version_util.h"
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include <gtest/gtest.h>
#include "kudu/util/status.h"
#include "kudu/util/test_macros.h"
#include "kudu/util/version_info.h"
using std::nullopt;
using std::string;
using std::pair;
using std::vector;
namespace kudu {
TEST(VersionUtilTest, TestVersion) {
const vector<pair<Version, string>> good_test_cases = {
{ { "0.0.0", 0, 0, 0, nullopt, "" }, "0.0.0" },
{ { "1.0.0", 1, 0, 0, nullopt, "" }, "1.0.0" },
{ { "1.1.0", 1, 1, 0, nullopt, "" }, "1.1.0" },
{ { "1.1.1", 1, 1, 1, nullopt, "" }, "1.1.1" },
{ { "1.1.1-", 1, 1, 1, nullopt, "" }, "1.1.1" },
{ { "1.1.1-0-1-2", 1, 1, 1, '-', "0-1-2" }, "1.1.1-0-1-2" },
{ { "1.10.100-1000.0", 1, 10, 100, '-', "1000.0" }, "1.10.100-1000.0" },
{ { "1.2.3-SNAPSHOT", 1, 2, 3, '-', "SNAPSHOT" }, "1.2.3-SNAPSHOT" },
{ { "1.8.0-x-SNAPSHOT", 1, 8, 0, '-', "x-SNAPSHOT" }, "1.8.0-x-SNAPSHOT" },
{ { "0.1.2-a-b-c-d", 0, 1, 2, '-', "a-b-c-d" }, "0.1.2-a-b-c-d" },
// no octals: leading zeros are just chopped off
{ { "00.01.010", 0, 1, 10, nullopt, "" }, "0.1.10" },
{ { " 0.1.2----suffix ", 0, 1, 2, '-', "---suffix" }, "0.1.2----suffix" },
{ { "0.1.2- - -x- -y- ", 0, 1, 2, '-', " - -x- -y-" }, "0.1.2- - -x- -y-" },
{ { "1.11.0.7.0.0.0-SNAPSHOT", 1, 11, 0, '.', "7.0.0.0-SNAPSHOT" }, "1.11.0.7.0.0.0-SNAPSHOT" },
};
for (const auto& test_case : good_test_cases) {
const auto& version = test_case.first;
const auto& canonical_str = test_case.second;
Version v;
ASSERT_OK(ParseVersion(version.raw_version, &v));
EXPECT_EQ(version, v);
EXPECT_EQ(canonical_str, v.ToString());
}
const vector<string> bad_test_cases = {
"",
" ",
"-",
" -",
"--",
" - - ",
"..",
"0.1",
"0.1.",
"0.1.+",
"+ 0.+ 1.+ 2",
"0.1.+-woops",
"0.1.2+",
"1..1",
".0.1",
" . . ",
"-0.1.2-013",
"0.-1.2-013",
"0.1.-2-013",
"1000,000.2999,999.999",
"1e10.0.1",
"1e+10.0.1",
"1e-1.0.1",
"1E+1.2.3",
"1E-5.0.1",
"foo",
"foo.1.0",
"a.b.c",
"0.x1.x2",
"0x0.0x1.0x2",
"1.bar.0",
"1.0.foo",
"1.0foo.bar",
"foo5-1.4.3",
"1-2-3",
"1.2-3",
"1-2.3",
"1-2-3-SNAPSHOT",
"1.2-3-SNAPSHOT",
"1-2.3-SNAPSHOT",
" 0 .1 .2 -x",
" 0 . 1 . 2 -x ",
"+1.+2.+3-6",
" +1 . +2 . +3 -100 .. ",
};
for (const auto& input_str : bad_test_cases) {
Version v;
const auto s = ParseVersion(input_str, &v);
ASSERT_TRUE(s.IsInvalidArgument())
<< s.ToString() << ": " << input_str << " ---> " << v.ToString();
}
}
// Sanity check: parse current Kudu version string and make sure the 'canonical'
// representation of the parsed version matches the 'raw' input as is.
TEST(VersionUtilTest, ParseCurrentKuduVersionString) {
const auto ver_string = VersionInfo::GetShortVersionInfo();
Version v;
const auto s = ParseVersion(ver_string, &v);
ASSERT_TRUE(s.ok()) << s.ToString();
EXPECT_EQ(ver_string, v.ToString());
}
} // namespace kudu