Tests passed.
This commit is contained in:
@@ -15,7 +15,7 @@ Public read actions:
|
||||
- `wget http://localhost:8123/object/squashkiwi:latest`
|
||||
- `wget http://localhost:8123/object/4528400792837739857`
|
||||
|
||||
- `curl http://loclahost:8123/exists/squashkiwi:latest`
|
||||
- `curl http://localhost:8123/exists/squashkiwi:latest`
|
||||
- `curl http://localhost:8123/exists/4528400792837739857`
|
||||
|
||||
- You can retrieve the hash for a given label and tag with, e.g.:
|
||||
|
@@ -143,6 +143,11 @@ void Server::setup_routes() {
|
||||
handle_get_hash(req, res);
|
||||
});
|
||||
|
||||
// Check if object exists by hash or label:tag
|
||||
server_.Get("/exists/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
handle_exists(req, res);
|
||||
});
|
||||
|
||||
// Get directory listing
|
||||
server_.Get("/dir", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
handle_get_directory(req, res);
|
||||
@@ -529,4 +534,48 @@ void Server::handle_append_tag(const httplib::Request& req, httplib::Response& r
|
||||
res.set_content(response.dump(), "application/json");
|
||||
}
|
||||
|
||||
void Server::handle_exists(const httplib::Request& req, httplib::Response& res) {
|
||||
const auto& key = req.matches[1].str();
|
||||
std::string hash_str = key;
|
||||
|
||||
// Check if the key is a label:tag format
|
||||
dbEntry entry;
|
||||
if (db_->get(key, entry)) {
|
||||
// Got it from label:tag, use the hash
|
||||
hash_str = entry.hash;
|
||||
}
|
||||
|
||||
// If we couldn't determine a hash
|
||||
if (hash_str.empty()) {
|
||||
nlohmann::json response = {{"result", "success"}, {"exists", false}};
|
||||
res.set_content(response.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to interpret the key as a hash directly
|
||||
uint64_t hash_value;
|
||||
try {
|
||||
hash_value = std::stoull(hash_str);
|
||||
} catch (const std::invalid_argument& e) {
|
||||
nlohmann::json response = {{"result", "success"}, {"exists", false}};
|
||||
res.set_content(response.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream oss;
|
||||
oss << hash_value;
|
||||
if (oss.str() != hash_str) {
|
||||
nlohmann::json response = {{"result", "success"}, {"exists", false}};
|
||||
res.set_content(response.dump(), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
// Hash is valid, check if the file exists
|
||||
std::filesystem::path file_path = config_.object_store_path / oss.str();
|
||||
bool exists = std::filesystem::exists(file_path) && std::filesystem::is_regular_file(file_path);
|
||||
|
||||
nlohmann::json response = {{"result", "success"}, {"exists", exists}};
|
||||
res.set_content(response.dump(), "application/json");
|
||||
}
|
||||
|
||||
} // namespace simple_object_storage
|
@@ -31,6 +31,7 @@ private:
|
||||
void handle_delete_tag(const httplib::Request& req, httplib::Response& res);
|
||||
void handle_delete_object(const httplib::Request& req, httplib::Response& res);
|
||||
void handle_append_tag(const httplib::Request& req, httplib::Response& res);
|
||||
void handle_exists(const httplib::Request& req, httplib::Response& res);
|
||||
std::pair<std::string, std::string> parse_label_tag(const std::string& label_tag) const;
|
||||
void add_file_metadata(const std::string &file_path, nlohmann::json &metadata) const;
|
||||
|
||||
|
44
test.sh
44
test.sh
@@ -3,9 +3,21 @@
|
||||
SCRIPT_DIR=$(dirname $0)
|
||||
SCRIPT_NAME=$(basename $0)
|
||||
|
||||
# FUNCTIONS
|
||||
function title() {
|
||||
echo "----------------------------------------"
|
||||
# Center the text
|
||||
local text="$1"
|
||||
local line_length=40
|
||||
local text_length=${#text}
|
||||
local padding=$(( (line_length - text_length) / 2 ))
|
||||
printf "%*s%s%*s\n" $padding "" "$text" $padding ""
|
||||
echo "----------------------------------------"
|
||||
}
|
||||
|
||||
|
||||
function die() {
|
||||
echo "error: $1"
|
||||
title "error: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -54,11 +66,15 @@ echo "md5sum of ${SCRIPT_DIR}/${SCRIPT_NAME} is ${MD5SUM}"
|
||||
|
||||
# download the object
|
||||
echo "downloading ${OBJECT_HASH} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1"
|
||||
curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1
|
||||
if ! curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1; then
|
||||
die "failed to download ${OBJECT_HASH}"
|
||||
fi
|
||||
|
||||
# download the object again via the label:tag
|
||||
echo "downloading ${BASE_TAG}:test1 to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2"
|
||||
curl -s "${BASE_URL}/object/${BASE_TAG}:test1" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2
|
||||
if ! curl -s "${BASE_URL}/object/${BASE_TAG}:test1" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2; then
|
||||
die "failed to download ${BASE_TAG}:test1"
|
||||
fi
|
||||
|
||||
# get md5sum of the downloaded file
|
||||
MD5SUM_DOWNLOADED1=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1 | awk '{print $1}')
|
||||
@@ -84,15 +100,22 @@ fi
|
||||
|
||||
# testing we can still download via the hash
|
||||
echo "testing we can still download via the hash"
|
||||
if ! curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3 | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to download via the hash"
|
||||
if ! curl -s "${BASE_URL}/exists/${OBJECT_HASH}" | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to check exists via the hash"
|
||||
fi
|
||||
|
||||
MD5SUM_DOWNLOADED3=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3 | awk '{print $1}')
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED3}" ] && die "md5sums do not match"
|
||||
# download the object
|
||||
echo "downloading ${OBJECT_HASH} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded4"
|
||||
if ! curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded4; then
|
||||
die "failed to download ${OBJECT_HASH}"
|
||||
fi
|
||||
|
||||
MD5SUM_DOWNLOADED4=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded4 | awk '{print $1}')
|
||||
MD5SUM=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME} | awk '{print $1}')
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED4}" ] && die "md5sums do not match"
|
||||
|
||||
# delete the downloaded file
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded4
|
||||
|
||||
# delete the object
|
||||
echo "deleting ${OBJECT_HASH}"
|
||||
@@ -103,9 +126,8 @@ fi
|
||||
# verify the object is deleted
|
||||
echo "verifying ${OBJECT_HASH} is deleted"
|
||||
DELETE_RESPONSE=$(curl -s "${BASE_URL}/object/${OBJECT_HASH}")
|
||||
echo "delete response: ${DELETE_RESPONSE}"
|
||||
if ! echo "${DELETE_RESPONSE}" | jq -r '.result' | grep -q 'success'; then
|
||||
if ! echo "${DELETE_RESPONSE}" | jq -r '.result' | grep -q 'error'; then
|
||||
die "failed to verify ${OBJECT_HASH} is deleted"
|
||||
fi
|
||||
|
||||
|
||||
title "ALL TESTS PASSED"
|
||||
|
@@ -1,107 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
SCRIPT_DIR=$(dirname $0)
|
||||
SCRIPT_NAME=$(basename $0)
|
||||
|
||||
|
||||
function die() {
|
||||
echo "error: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
# test jq is installed
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "jq could not be found"
|
||||
echo "sudo apt-get install jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# read ~/.config/simple_object_storage/config.json
|
||||
CONFIG_PATH="${HOME}/.config/simple_object_storage/config.json"
|
||||
if [ ! -f "${CONFIG_PATH}" ]; then
|
||||
echo "config file not found at ${CONFIG_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
CONFIG=$(cat "${CONFIG_PATH}")
|
||||
|
||||
# get the host and port from the config
|
||||
HOST=$(echo $CONFIG | jq -r '.host')
|
||||
PORT=$(echo $CONFIG | jq -r '.port')
|
||||
|
||||
# extract the first write token from the config
|
||||
WRITE_TOKEN=$(echo $CONFIG | jq -r '.write_tokens[0]')
|
||||
|
||||
BASE_URL="http://${HOST}:${PORT}"
|
||||
|
||||
BASE_TAG="autotest"
|
||||
|
||||
# test every action in the README.md file, leaving the system in the same state it was found
|
||||
# and print the output of each action
|
||||
|
||||
# upload this script as an object
|
||||
echo "uploading ${SCRIPT_DIR}/${SCRIPT_NAME} to ${BASE_TAG}:test1"
|
||||
OBJECT_HASH=$(curl -s "${BASE_URL}/upload?token=${WRITE_TOKEN}&labeltag=${BASE_TAG}:test1&filename=${SCRIPT_NAME}" -T ${SCRIPT_DIR}/${SCRIPT_NAME} | jq -r '.hash')
|
||||
echo "received hash ${OBJECT_HASH}"
|
||||
|
||||
# get md5sum of this file
|
||||
MD5SUM=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME} | awk '{print $1}')
|
||||
echo "md5sum of ${SCRIPT_DIR}/${SCRIPT_NAME} is ${MD5SUM}"
|
||||
|
||||
# download the object
|
||||
echo "downloading ${OBJECT_HASH} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded"
|
||||
curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded
|
||||
|
||||
# download the object again via the label:tag
|
||||
echo "downloading ${BASE_TAG}:test1 to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2"
|
||||
curl -s "${BASE_URL}/object/${BASE_TAG}:test1" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2
|
||||
|
||||
# get md5sum of the downloaded file
|
||||
MD5SUM_DOWNLOADED=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded | awk '{print $1}')
|
||||
echo "md5sum of ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded is ${MD5SUM_DOWNLOADED}"
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED}" ] && die "md5sums do not match"
|
||||
MD5SUM_DOWNLOADED2=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2 | awk '{print $1}')
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED2}" ] && die "md5sums do not match"
|
||||
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2
|
||||
|
||||
# delete the object tags
|
||||
echo "deleting tag ${BASE_TAG}:test1"
|
||||
if ! curl -s "${BASE_URL}/deletetag?token=${WRITE_TOKEN}&labeltag=${BASE_TAG}:test1" | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to delete tag ${BASE_TAG}:test1"
|
||||
fi
|
||||
|
||||
# testing we CANT download via the label:tag
|
||||
echo "testing we CANT download via the label:tag"
|
||||
if curl -s "${BASE_URL}/object/${BASE_TAG}:test1" | jq -r '.result' | grep -q 'success'; then
|
||||
die "downloaded via the label:tag"
|
||||
fi
|
||||
|
||||
# testing we can still download via the hash
|
||||
echo "testing we can still download via the hash"
|
||||
if ! curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3 | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to download via the hash"
|
||||
fi
|
||||
|
||||
MD5SUM_DOWNLOADED3=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3 | awk '{print $1}')
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED3}" ] && die "md5sums do not match"
|
||||
|
||||
# delete the downloaded file
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3
|
||||
|
||||
# delete the object
|
||||
echo "deleting ${OBJECT_HASH}"
|
||||
if ! curl -s "${BASE_URL}/deleteobject?token=${WRITE_TOKEN}&hash=${OBJECT_HASH}" | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to delete ${OBJECT_HASH}"
|
||||
fi
|
||||
|
||||
# verify the object is deleted
|
||||
echo "verifying ${OBJECT_HASH} is deleted"
|
||||
DELETE_RESPONSE=$(curl -s "${BASE_URL}/object/${OBJECT_HASH}")
|
||||
echo "delete response: ${DELETE_RESPONSE}"
|
||||
if ! echo "${DELETE_RESPONSE}" | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to verify ${OBJECT_HASH} is deleted"
|
||||
fi
|
||||
|
||||
|
@@ -1,111 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
SCRIPT_DIR=$(dirname $0)
|
||||
SCRIPT_NAME=$(basename $0)
|
||||
|
||||
|
||||
function die() {
|
||||
echo "error: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
# test jq is installed
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "jq could not be found"
|
||||
echo "sudo apt-get install jq"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# read ~/.config/simple_object_storage/config.json
|
||||
CONFIG_PATH="${HOME}/.config/simple_object_storage/config.json"
|
||||
if [ ! -f "${CONFIG_PATH}" ]; then
|
||||
echo "config file not found at ${CONFIG_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
CONFIG=$(cat "${CONFIG_PATH}")
|
||||
|
||||
# get the host and port from the config
|
||||
HOST=$(echo $CONFIG | jq -r '.host')
|
||||
PORT=$(echo $CONFIG | jq -r '.port')
|
||||
|
||||
# extract the first write token from the config
|
||||
WRITE_TOKEN=$(echo $CONFIG | jq -r '.write_tokens[0]')
|
||||
|
||||
BASE_URL="http://${HOST}:${PORT}"
|
||||
|
||||
BASE_TAG="autotest"
|
||||
|
||||
# test every action in the README.md file, leaving the system in the same state it was found
|
||||
# and print the output of each action
|
||||
|
||||
# upload this script as an object
|
||||
echo "uploading ${SCRIPT_DIR}/${SCRIPT_NAME} to ${BASE_TAG}:test1"
|
||||
OBJECT_HASH=$(curl -s "${BASE_URL}/upload?token=${WRITE_TOKEN}&labeltag=${BASE_TAG}:test1&filename=${SCRIPT_NAME}" -T ${SCRIPT_DIR}/${SCRIPT_NAME} | jq -r '.hash')
|
||||
echo "received hash ${OBJECT_HASH}"
|
||||
|
||||
# check the hash matches.
|
||||
CHECK_HASH=$(curl -s "${BASE_URL}/hash/${BASE_TAG}:test1" | jq -r '.hash')
|
||||
[ "${OBJECT_HASH}" != "${CHECK_HASH}" ] && die "hash does not match"
|
||||
|
||||
# get md5sum of this file
|
||||
MD5SUM=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME} | awk '{print $1}')
|
||||
echo "md5sum of ${SCRIPT_DIR}/${SCRIPT_NAME} is ${MD5SUM}"
|
||||
|
||||
# download the object
|
||||
echo "downloading ${OBJECT_HASH} to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1"
|
||||
curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1
|
||||
|
||||
# download the object again via the label:tag
|
||||
echo "downloading ${BASE_TAG}:test1 to ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2"
|
||||
curl -s "${BASE_URL}/object/${BASE_TAG}:test1" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2
|
||||
|
||||
# get md5sum of the downloaded file
|
||||
MD5SUM_DOWNLOADED1=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1 | awk '{print $1}')
|
||||
echo "md5sum of ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1 is ${MD5SUM_DOWNLOADED1}"
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED1}" ] && die "md5sums do not match"
|
||||
MD5SUM_DOWNLOADED2=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2 | awk '{print $1}')
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED2}" ] && die "md5sums do not match"
|
||||
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded1
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded2
|
||||
|
||||
# delete the object tags
|
||||
echo "deleting tag ${BASE_TAG}:test1"
|
||||
if ! curl -s "${BASE_URL}/deletetag?token=${WRITE_TOKEN}&labeltag=${BASE_TAG}:test1" | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to delete tag ${BASE_TAG}:test1"
|
||||
fi
|
||||
|
||||
# testing we CANT download via the label:tag
|
||||
echo "testing we CANT download via the label:tag"
|
||||
if curl -s "${BASE_URL}/object/${BASE_TAG}:test1" | jq -r '.result' | grep -q 'success'; then
|
||||
die "downloaded via the label:tag"
|
||||
fi
|
||||
|
||||
# testing we can still download via the hash
|
||||
echo "testing we can still download via the hash"
|
||||
if ! curl -s "${BASE_URL}/object/${OBJECT_HASH}" -o ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3 | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to download via the hash"
|
||||
fi
|
||||
|
||||
MD5SUM_DOWNLOADED3=$(md5sum ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3 | awk '{print $1}')
|
||||
[ "${MD5SUM}" != "${MD5SUM_DOWNLOADED3}" ] && die "md5sums do not match"
|
||||
|
||||
# delete the downloaded file
|
||||
rm ${SCRIPT_DIR}/${SCRIPT_NAME}.downloaded3
|
||||
|
||||
# delete the object
|
||||
echo "deleting ${OBJECT_HASH}"
|
||||
if ! curl -s "${BASE_URL}/deleteobject?token=${WRITE_TOKEN}&hash=${OBJECT_HASH}" | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to delete ${OBJECT_HASH}"
|
||||
fi
|
||||
|
||||
# verify the object is deleted
|
||||
echo "verifying ${OBJECT_HASH} is deleted"
|
||||
DELETE_RESPONSE=$(curl -s "${BASE_URL}/object/${OBJECT_HASH}")
|
||||
echo "delete response: ${DELETE_RESPONSE}"
|
||||
if ! echo "${DELETE_RESPONSE}" | jq -r '.result' | grep -q 'success'; then
|
||||
die "failed to verify ${OBJECT_HASH} is deleted"
|
||||
fi
|
||||
|
||||
|
Reference in New Issue
Block a user