summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/other_tools/TARGETS5
-rw-r--r--test/other_tools/just_mr/TARGETS30
-rw-r--r--test/other_tools/just_mr/create_test_archives.cpp133
-rw-r--r--test/other_tools/just_mr/just-mr.test.sh200
4 files changed, 367 insertions, 1 deletions
diff --git a/test/other_tools/TARGETS b/test/other_tools/TARGETS
index 305c34af..c7a4cfe0 100644
--- a/test/other_tools/TARGETS
+++ b/test/other_tools/TARGETS
@@ -1,6 +1,9 @@
{ "TESTS":
{ "type": "install"
, "tainted": ["test"]
- , "dirs": [[["./", "git_operations", "TESTS"], "git_operations"]]
+ , "dirs":
+ [ [["./", "git_operations", "TESTS"], "git_operations"]
+ , [["./", "just_mr", "TESTS"], "just_mr"]
+ ]
}
}
diff --git a/test/other_tools/just_mr/TARGETS b/test/other_tools/just_mr/TARGETS
new file mode 100644
index 00000000..d3b016a5
--- /dev/null
+++ b/test/other_tools/just_mr/TARGETS
@@ -0,0 +1,30 @@
+{ "just_mr_install":
+ { "type": "install"
+ , "files": {"bin/just-mr-under-test": ["src/other_tools/just_mr", "just-mr"]}
+ }
+, "create_test_archives":
+ { "type": ["@", "rules", "CC", "binary"]
+ , "tainted": ["test"]
+ , "name": ["create_test_archives"]
+ , "srcs": ["create_test_archives.cpp"]
+ , "private-deps":
+ [ ["src/buildtool/file_system", "file_system_manager"]
+ , ["src/buildtool/logging", "logging"]
+ , ["src/utils/cpp", "archive_ops"]
+ , ["src/utils/cpp", "tmp_dir"]
+ ]
+ , "private-ldflags": ["-lpthread"]
+ , "stage": ["src"]
+ }
+, "just_mr_mp":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["just_mr_mp"]
+ , "test": ["just-mr.test.sh"]
+ , "deps":
+ [ "create_test_archives"
+ , ["test/utils", "test_utils_install"]
+ , "just_mr_install"
+ ]
+ }
+, "TESTS": {"type": "install", "tainted": ["test"], "deps": ["just_mr_mp"]}
+}
diff --git a/test/other_tools/just_mr/create_test_archives.cpp b/test/other_tools/just_mr/create_test_archives.cpp
new file mode 100644
index 00000000..fbda0f6e
--- /dev/null
+++ b/test/other_tools/just_mr/create_test_archives.cpp
@@ -0,0 +1,133 @@
+// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed 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 <unordered_map>
+
+#include "src/buildtool/file_system/file_system_manager.hpp"
+#include "src/buildtool/logging/log_config.hpp"
+#include "src/buildtool/logging/log_sink_cmdline.hpp"
+#include "src/utils/cpp/archive_ops.hpp"
+#include "src/utils/cpp/tmp_dir.hpp"
+
+namespace {
+
+void SetupDefaultLogging() {
+ LogConfig::SetLogLimit(LogLevel::Progress);
+ LogConfig::SetSinks({LogSinkCmdLine::CreateFactory()});
+}
+
+using file_t = std::pair</*content*/ std::string, ObjectType>;
+using filetree_t = std::unordered_map<std::string, file_t>;
+/*
+Structure of content tree:
+
++--root
+ +--bar
+ +--foo
+ +--baz
+ +--bar
+ +--foo
+*/
+auto const kExpected = filetree_t{{"root", {"", ObjectType::Tree}},
+ {"root/foo", {"foo", ObjectType::File}},
+ {"root/bar", {"bar", ObjectType::File}},
+ {"root/baz", {"", ObjectType::Tree}},
+ {"root/baz/foo", {"foo", ObjectType::File}},
+ {"root/baz/bar", {"bar", ObjectType::File}}};
+
+void create_files(std::filesystem::path const& destDir = ".") {
+ for (auto const& [path, file] : kExpected) {
+ auto const& [content, type] = file;
+ switch (type) {
+ case ObjectType::File: {
+ if (not FileSystemManager::WriteFile(content, destDir / path)) {
+ Logger::Log(LogLevel::Error,
+ "Could not create test file at path {}",
+ (destDir / path).string());
+ std::exit(1);
+ };
+ } break;
+ case ObjectType::Tree: {
+ if (not FileSystemManager::CreateDirectory(destDir / path)) {
+ Logger::Log(LogLevel::Error,
+ "Could not create test dir at path {}",
+ (destDir / path).string());
+ std::exit(1);
+ };
+ } break;
+ default: {
+ Logger::Log(LogLevel::Error,
+ "File system failure in creating test archive");
+ std::exit(1);
+ }
+ }
+ }
+}
+
+} // namespace
+
+/// \brief This code will create a zip and a tar.gz archives to be used in
+/// tests. The archives are created in a tmp directory and then posted in the
+/// current directory. Caller must guarantee write rights in current directory.
+auto main() -> int {
+ // setup logging
+ SetupDefaultLogging();
+ // make tmp dir
+ auto curr_path = FileSystemManager::GetCurrentDirectory();
+ auto tmp_dir = TmpDir::Create(curr_path);
+ if (not tmp_dir) {
+ Logger::Log(LogLevel::Error,
+ "Could not create tmp dir for test archives at path {}",
+ curr_path.string());
+ return 1;
+ }
+ // create the content tree
+ create_files(tmp_dir->GetPath());
+ // create the archives
+ // 1. move to correct directory
+ {
+ auto anchor = FileSystemManager::ChangeDirectory(tmp_dir->GetPath());
+ // 2. create the archvies wrt to current directory
+ std::optional<std::string> res{std::nullopt};
+ res = ArchiveOps::CreateArchive(
+ ArchiveType::kArchiveTypeZip, "zip_repo.zip", "root");
+ if (res) {
+ Logger::Log(LogLevel::Error,
+ "Creating test zip archive failed with:\n{}",
+ *res);
+ return 1;
+ }
+ res = ArchiveOps::CreateArchive(
+ ArchiveType::kArchiveTypeTarGz, "tgz_repo.tar.gz", "root");
+ if (res) {
+ Logger::Log(LogLevel::Error,
+ "Creating test tar.gz archive failed with:\n{}",
+ *res);
+ return 1;
+ }
+ } // anchor released
+ // 3. move archives to their correct location
+ if (not FileSystemManager::Rename(tmp_dir->GetPath() / "zip_repo.zip",
+ "zip_repo.zip")) {
+ Logger::Log(LogLevel::Error, "Renaming zip archive failed");
+ return 1;
+ }
+ if (not FileSystemManager::Rename(tmp_dir->GetPath() / "tgz_repo.tar.gz",
+ "tgz_repo.tar.gz")) {
+ Logger::Log(LogLevel::Error, "Renaming tar.gz archive failed");
+ return 1;
+ }
+ // Done! Tmp dir will be cleaned automatically
+ return 0;
+}
diff --git a/test/other_tools/just_mr/just-mr.test.sh b/test/other_tools/just_mr/just-mr.test.sh
new file mode 100644
index 00000000..2fa00ec3
--- /dev/null
+++ b/test/other_tools/just_mr/just-mr.test.sh
@@ -0,0 +1,200 @@
+#!/bin/sh
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed 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.
+
+set -eu
+
+# cleanup of http.server; pass server_pid as arg
+server_cleanup() {
+ echo "Shut down HTTP server"
+ # send SIGTERM
+ kill ${1} & res=$!
+ wait ${res}
+ echo "done"
+}
+
+readonly ROOT=`pwd`
+readonly WRKDIR="${TEST_TMPDIR}/wrkdir"
+
+# set the just-mr versions to be run
+# Python version won't be able to find wget, unzip, and tar
+
+# readonly JUST_MR_PY="${ROOT}/bin/just-mr.py"
+readonly JUST_MR_CPP="${ROOT}/bin/just-mr-under-test"
+
+# set paths
+readonly SERVER_ROOT="${TEST_TMPDIR}/server-root"
+readonly FILE_ROOT="${TEST_TMPDIR}/file-root"
+readonly GIT_ROOT="${TEST_TMPDIR}/git-root"
+readonly TEST_ROOT="${TEST_TMPDIR}/test-root"
+
+# move to where server will be posted
+mkdir -p "${SERVER_ROOT}"
+cd "${SERVER_ROOT}"
+
+echo "Setup archive repos"
+# create the archives in current dir
+${ROOT}/src/create_test_archives
+
+# store zip repo info
+readonly ZIP_REPO_CONTENT=$(git hash-object zip_repo.zip)
+readonly ZIP_REPO_SHA256=$(sha256sum zip_repo.zip | awk '{print $1}')
+readonly ZIP_REPO_SHA512=$(sha512sum zip_repo.zip | awk '{print $1}')
+# store tar.gz repo info
+readonly TGZ_REPO_CONTENT=$(git hash-object tgz_repo.tar.gz)
+readonly TGZ_REPO_SHA256=$(sha256sum tgz_repo.tar.gz | awk '{print $1}')
+readonly TGZ_REPO_SHA512=$(sha512sum tgz_repo.tar.gz | awk '{print $1}')
+
+echo "Set up file repos"
+mkdir -p "${FILE_ROOT}/test_dir1"
+echo test > "${FILE_ROOT}/test_dir1/test_file"
+mkdir -p "${FILE_ROOT}/test_dir2/test_dir3"
+echo test > "${FILE_ROOT}/test_dir2/test_dir3/test_file"
+
+echo "Set up local git repo"
+# NOTE: Libgit2 has no support for Git bundles yet
+mkdir -p "${GIT_ROOT}"
+(
+ cd "${GIT_ROOT}" \
+ && mkdir -p foo/bar \
+ && echo foo > foo.txt \
+ && echo bar > foo/bar.txt \
+ && git init -b test \
+ && git config user.email "nobody@example.org" \
+ && git config user.name "Nobody" \
+ && git add . \
+ && git commit -m "test" --date="1970-01-01T00:00Z"
+)
+# the root commit ID is known -- see git_repo.test.cpp
+readonly GIT_REPO_COMMIT="$(cd "${GIT_ROOT}" && git rev-parse HEAD)"
+
+echo "Publish remote repos to HTTP server"
+# start Python server as remote repos location
+port_file="$(mktemp -t port_XXXXXX -p "${TEST_TMPDIR}")"
+python3 -u "${ROOT}/utils/run_test_server.py" >${port_file} & server_pid=$!
+sleep 1s # give some time to set up properly
+# set up cleanup of http server
+trap "server_cleanup ${server_pid}" INT TERM EXIT
+# get port number as variable
+port_num="$(cat ${port_file})"
+
+echo "Create local build env"
+# the build root
+readonly BUILDROOT=${WRKDIR}/.cache/just
+mkdir -p ${BUILDROOT}
+# a distdir
+readonly DISTFILES=${WRKDIR}/.distfiles
+mkdir -p ${DISTFILES}
+readonly DISTDIR_ARGS="--distdir ${DISTFILES}"
+
+echo "Create repos.json"
+mkdir -p "${TEST_ROOT}"
+cd "${TEST_ROOT}"
+cat > test-repos.json <<EOF
+{ "repositories":
+ { "zip_repo":
+ { "repository":
+ { "type": "zip"
+ , "content": "${ZIP_REPO_CONTENT}"
+ , "distfile": "zip_repo.zip"
+ , "fetch": "http://127.0.0.1:${port_num}/zip_repo.zip"
+ , "sha256": "${ZIP_REPO_SHA256}"
+ , "sha512": "${ZIP_REPO_SHA512}"
+ , "subdir": "root"
+ }
+ , "bindings": {"tgz_repo": "tgz_repo", "distdir_repo": "distdir_repo"}
+ }
+ , "tgz_repo":
+ { "repository":
+ { "type": "archive"
+ , "content": "${TGZ_REPO_CONTENT}"
+ , "distfile": "tgz_repo.tar.gz"
+ , "fetch": "http://127.0.0.1:${port_num}/tgz_repo.tar.gz"
+ , "sha256": "${TGZ_REPO_SHA256}"
+ , "sha512": "${TGZ_REPO_SHA512}"
+ , "subdir": "root/baz"
+ }
+ , "bindings": {"git_repo": "git_repo"}
+ }
+ , "git_repo":
+ { "repository":
+ { "type": "git"
+ , "repository": "${GIT_ROOT}"
+ , "branch": "test"
+ , "commit": "${GIT_REPO_COMMIT}"
+ , "subdir": "foo"
+ }
+ }
+ , "file_repo1":
+ { "repository":
+ { "type": "file"
+ , "path": "${FILE_ROOT}/test_dir1"
+ }
+ }
+ , "file_repo2":
+ { "repository":
+ { "type": "file"
+ , "path": "${FILE_ROOT}/test_dir2"
+ , "pragma": {"to_git": true}
+ }
+ , "bindings": {"file_repo1": "file_repo1"}
+ }
+ , "distdir_repo":
+ { "repository":
+ { "type": "distdir"
+ , "repositories": ["git_repo", "zip_repo", "file_repo2"]
+ }
+ , "bindings": {"file_repo1": "file_repo1"}
+ }
+ }
+}
+EOF
+
+echo "Set up test cases"
+cat > test_setup.sh <<EOF
+CONFIG_CPP="\$(${JUST_MR_CPP} -C test-repos.json --norc --local-build-root ${BUILDROOT} ${DISTDIR_ARGS} -j 32 setup --all)"
+if [ ! -s "\${CONFIG_CPP}" ]; then
+ exit 1
+fi
+EOF
+
+echo "Run 8 test cases in parallel"
+error=false
+
+sh test_setup.sh & res1=$!
+sh test_setup.sh & res2=$!
+sh test_setup.sh & res3=$!
+sh test_setup.sh & res4=$!
+
+wait ${res1}
+if [ $? -ne 0 ]; then
+ error=true
+fi
+wait ${res2}
+if [ $? -ne 0 ]; then
+ error=true
+fi
+wait ${res3}
+if [ $? -ne 0 ]; then
+ error=true
+fi
+wait ${res4}
+if [ $? -ne 0 ]; then
+ error=true
+fi
+
+# check test status
+if [ $error = true ]; then
+ exit 1
+fi