#!/usr/bin/env bash
set -e
# ----------------------------------------------------------------------
# File: eos-timestamp-test
# Author: Aritz Brosa Iartza - CERN
# Mihai Patrascoiu - CERN
# ----------------------------------------------------------------------
# ******************************************************************************
# EOS - the CERN Disk Storage System
# Copyright (C) 2020 CERN/Switzerland
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# ******************************************************************************
#------------------------------------------------------------------------------
# Description: Script testing timestamp functionality of EOS.
# The following test scenarios are executed:
# - File is created => mtime, ctime and btime are identical
# - Content is modified => mtime and ctime change
# - Metadata is changed => only ctime changes
# - Touch is performed => mtime and ctime change
#
# Usage: eos-timestamp-test []
#------------------------------------------------------------------------------
# Global timestamp variables used by utility function
mtime=0
ctime=0
btime=0
# Global return code
rc=0
#------------------------------------------------------------------------------
# Helper functions
#------------------------------------------------------------------------------
function usage() {
echo "Usage: $0 []"
echo " - the /eos// to access"
echo " - optional MGM hostname (will use EOS_MGM_URL env variable otherwise)"
echo ""
exit 1
}
function retrieve_timestamps() {
local fileinfo=`eos -j fileinfo $1`
mtime=`echo ${fileinfo} | jq '(.mtime|tostring) + "." + (.mtime_ns|tostring)'`
ctime=`echo ${fileinfo} | jq '(.ctime|tostring) + "." + (.ctime_ns|tostring)'`
btime=`echo ${fileinfo} | jq '(.btime|tostring) + "." + (.btime_ns|tostring)'`
echo "mtime=${mtime} ctime=${ctime} btime=${btime}"
}
#------------------------------------------------------------------------------
# Global setup
#------------------------------------------------------------------------------
if [[ $# -eq 0 || $# -gt 2 ]]; then
usage
fi
# Setup EOS instance variables
EOS_INSTANCE_NAME=$1
EOS_MGM_HOSTNAME=$2
if [[ -z "$EOS_MGM_HOSTNAME" ]]; then
if [[ -n "$EOS_MGM_URL" ]]; then
EOS_MGM_HOSTNAME=${EOS_MGM_URL#root://}
EOS_MGM_HOSTNAME=${EOS_MGM_HOSTNAME%:1094/}
else
EOS_MGM_HOSTNAME=localhost
fi
fi
export EOS_MGM_URL=${EOS_MGM_HOSTNAME}
echo "EOS_INSTANCE_NAME=${EOS_INSTANCE_NAME}"
echo "EOS_MGM_HOSTNAME=${EOS_MGM_HOSTNAME}"
#------------------------------------------------------------------------------
# Testing scenario
#------------------------------------------------------------------------------
# Initial setup
eos mkdir -p /eos/${EOS_INSTANCE_NAME}/timestamp_tests/
touch /eos1/${EOS_INSTANCE_NAME}/timestamp_tests/file
printf "\nRetrieving initial timestamps\n"
retrieve_timestamps /eos/${EOS_INSTANCE_NAME}/timestamp_tests/file
mtime_init=$mtime
ctime_init=$ctime
btime_init=$btime
# TEST: All timestamps should be identical
# Note: Compare only the integer part of the timestamp for birthtime
# (btime has a slight btime_ns difference)
if [[ ${mtime_init} != ${ctime_init} || ${mtime_init%.*} != ${btime_init%.*} ]]; then
echo "Timestamps are not equal after test file creation" >&2
rc=1
fi
## File content modification scenario
sleep 1
printf "\nRetrieving timestamps after content modification\n"
echo 'start' > /eos1/${EOS_INSTANCE_NAME}/timestamp_tests/file
retrieve_timestamps /eos/${EOS_INSTANCE_NAME}/timestamp_tests/file
mtime_cont=$mtime
ctime_cont=$ctime
btime_cont=$btime
# TEST: Content modification should affect mtime and ctime
if [[ ${mtime_init} == ${mtime_cont} || ${ctime_init} == ${ctime_cont} || ${btime_init} != ${btime_cont} ]]; then
echo "Content modification timestamps not behaving as expected" >&2
if [[ ${mtime_init} == ${mtime_cont} ]]; then echo "-- mtime did not change" >&2 ; fi
if [[ ${ctime_init} == ${ctime_cont} ]]; then echo "-- ctime did not change" >&2 ; fi
if [[ ${btime_init} != ${btime_cont} ]]; then echo "-- btime changed but it should not have" >&2 ; fi
rc=1
fi
## File metadata change scenario
sleep 1
printf "\nRetrieving timestamps after metadata-only modification\n"
eos attr set user.eos.dummy="value" /eos/${EOS_INSTANCE_NAME}/timestamp_tests/file
retrieve_timestamps /eos/${EOS_INSTANCE_NAME}/timestamp_tests/file
mtime_metad=$mtime
ctime_metad=$ctime
btime_metad=$btime
# TEST: Metadata-only change should affect only ctime
if [[ ${mtime_cont} != ${mtime_metad} || ${ctime_cont} == ${ctime_metad} || ${btime_cont} != ${btime_metad} ]]; then
echo "Metadata modification timestamps not behaving as expected" >&2
if [[ ${mtime_cont} != ${mtime_metad} ]]; then echo "-- mtime changed but it should not have" >&2 ; fi
if [[ ${ctime_cont} == ${ctime_metad} ]]; then echo "-- ctime did not change" >&2 ; fi
if [[ ${btime_cont} != ${btime_metad} ]]; then echo "-- btime changed but it should not have" >&2 ; fi
rc=1
fi
## Touch scenario
sleep 1
printf "\nRetrieving timestamps after touch\n"
eos touch /eos/${EOS_INSTANCE_NAME}/timestamp_tests/file > /dev/null
retrieve_timestamps /eos/${EOS_INSTANCE_NAME}/timestamp_tests/file
mtime_touch=$mtime
ctime_touch=$ctime
btime_touch=$btime
# TEST: Touch should affect mtime and ctime
if [[ ${mtime_metad} == ${mtime_touch} || ${ctime_metad} == ${ctime_touch} || ${btime_metad} != ${btime_touch} ]]; then
echo "Touch command timestamps not behaving as expected" >&2
if [[ ${mtime_metad} == ${mtime_touch} ]]; then echo "-- mtime did not change" >&2 ; fi
if [[ ${ctime_metad} == ${ctime_touch} ]]; then echo "-- ctime did not change" >&2 ; fi
if [[ ${btime_metad} != ${btime_touch} ]]; then echo "-- btime changed but it should not have" >&2 ; fi
rc=1
fi
# Clean-up
eos rm /eos/dockertest/timestamp_tests/*
eos rmdir /eos/dockertest/timestamp_tests/
exit ${rc}