#!/bin/bash ############################################################################### # Gitea Git Functionality Test Suite # Tests: clone, commit, push, pull, branch, merge, conflict resolution, tags ############################################################################### # Configuration GITEA_URL="https://git.domverse-berlin.eu" GITEA_USER="domverse" GITEA_TOKEN="${GITEA_TOKEN:-74d3ae59375a1cf2b4bc78b98e4de9e4208413ce}" TEST_REPO="test-$(head -c 6 /dev/urandom | base64 | tr -dc 'a-z0-9' | head -c 8)" TEST_DIR="/tmp/gitea-test-$$" API_URL="${GITEA_URL}/api/v1" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Counters TESTS_TOTAL=0 TESTS_PASSED=0 TESTS_FAILED=0 ############################################################################### # Helper Functions ############################################################################### log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[✓]${NC} $1" ((TESTS_PASSED++)) ((TESTS_TOTAL++)) } log_fail() { echo -e "${RED}[✗]${NC} $1" ((TESTS_FAILED++)) ((TESTS_TOTAL++)) } log_step() { echo -e "\n${YELLOW}==>${NC} $1" } cleanup() { log_step "Cleanup" # Remove local test directory if [ -d "$TEST_DIR" ]; then rm -rf "$TEST_DIR" log_info "Removed test directory: $TEST_DIR" fi # Delete test repository via API if [ -n "$TEST_REPO" ]; then log_info "Deleting test repository: $TEST_REPO" curl -k -s -X DELETE \ -H "Authorization: token ${GITEA_TOKEN}" \ "${API_URL}/repos/${GITEA_USER}/${TEST_REPO}" \ -o /dev/null 2>&1 fi } # Trap to ensure cleanup on exit trap cleanup EXIT ############################################################################### # Test Functions ############################################################################### test_git_installed() { log_step "Test 1: Git Installation" if command -v git &> /dev/null; then GIT_VERSION=$(git --version) log_success "Git is installed: $GIT_VERSION" return 0 else log_fail "Git is not installed" return 1 fi } test_gitea_api_access() { log_step "Test 2: Gitea API Access" local response=$(curl -k -s -w "%{http_code}" \ -H "Authorization: token ${GITEA_TOKEN}" \ "${API_URL}/user" \ -o /tmp/api_response.json) if [ "$response" = "200" ]; then local username=$(cat /tmp/api_response.json | grep -o '"username":"[^"]*' | cut -d'"' -f4) log_success "API authentication successful (user: $username)" return 0 else log_fail "API authentication failed (HTTP $response)" return 1 fi } test_create_repository() { log_step "Test 3: Create Repository via API" local response=$(curl -k -s -w "%{http_code}" \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -X POST "${API_URL}/user/repos" \ -d "{\"name\":\"${TEST_REPO}\",\"description\":\"Automated test repository\",\"private\":false,\"auto_init\":false,\"default_branch\":\"main\"}" \ -o /tmp/create_repo.json) if [ "$response" = "201" ]; then log_success "Repository created: ${GITEA_USER}/${TEST_REPO}" return 0 else log_fail "Failed to create repository (HTTP $response)" cat /tmp/create_repo.json return 1 fi } test_git_clone() { log_step "Test 4: Git Clone (HTTPS)" mkdir -p "$TEST_DIR" cd "$TEST_DIR" || return 1 # Use token in clone URL for authentication local clone_url="https://${GITEA_USER}:${GITEA_TOKEN}@git.domverse-berlin.eu/${GITEA_USER}/${TEST_REPO}.git" if git clone "$clone_url" 2>&1 | tee /tmp/git_clone.log; then if [ -d "${TEST_REPO}/.git" ]; then log_success "Repository cloned successfully" cd "${TEST_REPO}" || return 1 return 0 else log_fail "Clone succeeded but .git directory not found" return 1 fi else log_fail "Git clone failed" cat /tmp/git_clone.log return 1 fi } test_git_config() { log_step "Test 5: Git Configuration" cd "${TEST_DIR}/${TEST_REPO}" || return 1 git config user.name "Test User" git config user.email "test@example.com" git config init.defaultBranch main local name=$(git config user.name) local email=$(git config user.email) if [ "$name" = "Test User" ] && [ "$email" = "test@example.com" ]; then log_success "Git config set successfully" return 0 else log_fail "Git config failed" return 1 fi } test_initial_commit() { log_step "Test 6: Initial Commit" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # Ensure we're on the main branch git checkout -b main 2>/dev/null || true # Create README echo "# ${TEST_REPO}" > README.md echo "This is an automated test repository." >> README.md git add README.md if git commit -m "Initial commit: Add README" 2>&1 | tee /tmp/git_commit.log; then log_success "Initial commit created" return 0 else log_fail "Initial commit failed" cat /tmp/git_commit.log return 1 fi } test_git_push() { log_step "Test 7: Git Push to Remote" cd "${TEST_DIR}/${TEST_REPO}" || return 1 if git push -u origin main 2>&1 | tee /tmp/git_push.log; then log_success "Push to remote successful (main branch)" return 0 else log_fail "Git push failed" cat /tmp/git_push.log return 1 fi } test_git_pull() { log_step "Test 8: Git Pull from Remote" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # Make a change via API to test pull local current_branch=$(git branch --show-current) if git pull origin "$current_branch" 2>&1 | tee /tmp/git_pull.log; then log_success "Pull from remote successful" return 0 else log_fail "Git pull failed" cat /tmp/git_pull.log return 1 fi } test_multiple_commits() { log_step "Test 9: Multiple Commits" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # First commit echo "## Features" >> README.md git add README.md git commit -m "Add features section" > /dev/null # Second commit echo "- Feature 1" >> README.md git add README.md git commit -m "Add feature 1" > /dev/null # Third commit echo "- Feature 2" >> README.md git add README.md git commit -m "Add feature 2" > /dev/null # Push all commits local current_branch=$(git branch --show-current) if git push origin "$current_branch" > /dev/null 2>&1; then local commit_count=$(git rev-list --count HEAD) log_success "Multiple commits pushed (total commits: $commit_count)" return 0 else log_fail "Failed to push multiple commits" return 1 fi } test_branch_create() { log_step "Test 10: Create Branch" cd "${TEST_DIR}/${TEST_REPO}" || return 1 if git checkout -b feature/test-feature 2>&1 | tee /tmp/git_branch.log; then local current_branch=$(git branch --show-current) if [ "$current_branch" = "feature/test-feature" ]; then log_success "Branch created and checked out: feature/test-feature" return 0 else log_fail "Branch created but checkout failed" return 1 fi else log_fail "Branch creation failed" cat /tmp/git_branch.log return 1 fi } test_branch_commit_push() { log_step "Test 11: Commit and Push to Branch" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # Make changes in feature branch echo "# Feature Branch Changes" > FEATURE.md git add FEATURE.md git commit -m "Add feature branch file" > /dev/null if git push -u origin feature/test-feature 2>&1 | tee /tmp/git_push_branch.log; then log_success "Feature branch pushed to remote" return 0 else log_fail "Failed to push feature branch" cat /tmp/git_push_branch.log return 1 fi } test_branch_switch() { log_step "Test 12: Switch Between Branches" cd "${TEST_DIR}/${TEST_REPO}" || return 1 local main_branch=$(git branch -r | grep -o 'origin/main\|origin/master' | head -1 | cut -d'/' -f2) # Switch to main if git checkout "$main_branch" > /dev/null 2>&1; then local current=$(git branch --show-current) if [ "$current" = "$main_branch" ]; then # Switch back to feature if git checkout feature/test-feature > /dev/null 2>&1; then current=$(git branch --show-current) if [ "$current" = "feature/test-feature" ]; then log_success "Branch switching works correctly" return 0 fi fi fi fi log_fail "Branch switching failed" return 1 } test_merge() { log_step "Test 13: Merge Branch" cd "${TEST_DIR}/${TEST_REPO}" || return 1 local main_branch=$(git branch -r | grep -o 'origin/main\|origin/master' | head -1 | cut -d'/' -f2) # Switch to main git checkout "$main_branch" > /dev/null 2>&1 # Merge feature branch if git merge feature/test-feature -m "Merge feature/test-feature into $main_branch" 2>&1 | tee /tmp/git_merge.log; then # Push merged changes if git push origin "$main_branch" > /dev/null 2>&1; then log_success "Branch merged and pushed successfully" return 0 else log_fail "Merge successful but push failed" return 1 fi else log_fail "Merge failed" cat /tmp/git_merge.log return 1 fi } test_conflict_handling() { log_step "Test 14: Conflict Detection and Resolution" cd "${TEST_DIR}/${TEST_REPO}" || return 1 local main_branch=$(git branch --show-current) # Create conflicting branch git checkout -b conflict-branch > /dev/null 2>&1 echo "Change from conflict branch" > conflict.txt git add conflict.txt git commit -m "Add conflict.txt in conflict-branch" > /dev/null # Switch back and make conflicting change git checkout "$main_branch" > /dev/null 2>&1 echo "Change from main branch" > conflict.txt git add conflict.txt git commit -m "Add conflict.txt in $main_branch" > /dev/null # Try to merge (should conflict) if git merge conflict-branch 2>&1 | grep -q "CONFLICT"; then log_success "Conflict detected correctly" # Resolve conflict echo "Resolved content" > conflict.txt git add conflict.txt if git commit -m "Resolve merge conflict" > /dev/null 2>&1; then log_success "Conflict resolution successful" return 0 else log_fail "Conflict resolution commit failed" return 1 fi else log_fail "Conflict detection failed or merge succeeded unexpectedly" return 1 fi } test_git_tag() { log_step "Test 15: Git Tags" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # Create annotated tag if git tag -a v1.0.0 -m "Version 1.0.0" 2>&1 | tee /tmp/git_tag.log; then # Push tag to remote if git push origin v1.0.0 > /dev/null 2>&1; then log_success "Tag created and pushed: v1.0.0" return 0 else log_fail "Tag created but push failed" return 1 fi else log_fail "Tag creation failed" cat /tmp/git_tag.log return 1 fi } test_git_log() { log_step "Test 16: Git Log and History" cd "${TEST_DIR}/${TEST_REPO}" || return 1 local commit_count=$(git rev-list --count HEAD) if [ "$commit_count" -gt 0 ]; then log_success "Git log accessible (commits: $commit_count)" return 0 else log_fail "Git log failed or no commits found" return 1 fi } test_git_status() { log_step "Test 17: Git Status" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # Make a change echo "Test status" > status-test.txt if git status | grep -q "status-test.txt"; then # Clean up rm status-test.txt log_success "Git status works correctly" return 0 else log_fail "Git status failed" return 1 fi } test_git_diff() { log_step "Test 18: Git Diff" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # Make a change echo "Test diff" >> README.md if git diff README.md | grep -q "Test diff"; then # Discard change git checkout -- README.md log_success "Git diff works correctly" return 0 else log_fail "Git diff failed" return 1 fi } test_gitignore() { log_step "Test 19: .gitignore Functionality" cd "${TEST_DIR}/${TEST_REPO}" || return 1 # Create .gitignore echo "*.log" > .gitignore echo "temp/" >> .gitignore # Create ignored files echo "test" > test.log mkdir -p temp echo "test" > temp/test.txt git add .gitignore > /dev/null 2>&1 # Check if ignored files are not tracked if git status | grep -q ".gitignore" && ! git status | grep -q "test.log"; then git commit -m "Add .gitignore" > /dev/null log_success ".gitignore works correctly" return 0 else log_fail ".gitignore test failed" return 1 fi } test_remote_info() { log_step "Test 20: Remote Repository Info" cd "${TEST_DIR}/${TEST_REPO}" || return 1 local remote_url=$(git remote get-url origin) if [[ "$remote_url" == *"git.domverse-berlin.eu"* ]]; then log_success "Remote URL configured: $remote_url" return 0 else log_fail "Remote URL incorrect: $remote_url" return 1 fi } ############################################################################### # Main Test Execution ############################################################################### main() { echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║ Gitea Git Functionality Test Suite ║${NC}" echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}" echo "" echo -e "${YELLOW}Gitea URL:${NC} $GITEA_URL" echo -e "${YELLOW}Test User:${NC} $GITEA_USER" echo -e "${YELLOW}Test Repo:${NC} $TEST_REPO" echo -e "${YELLOW}Test Dir:${NC} $TEST_DIR" echo "" # Run all tests test_git_installed || exit 1 test_gitea_api_access || exit 1 test_create_repository || exit 1 test_git_clone || exit 1 test_git_config || exit 1 test_initial_commit || exit 1 test_git_push || exit 1 test_git_pull || exit 1 test_multiple_commits || exit 1 test_branch_create || exit 1 test_branch_commit_push || exit 1 test_branch_switch || exit 1 test_merge || exit 1 test_conflict_handling || exit 1 test_git_tag || exit 1 test_git_log || exit 1 test_git_status || exit 1 test_git_diff || exit 1 test_gitignore || exit 1 test_remote_info || exit 1 # Summary echo "" echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║ Test Summary ║${NC}" echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}" echo "" echo -e "Total Tests: ${TESTS_TOTAL}" echo -e "${GREEN}Passed: ${TESTS_PASSED}${NC}" if [ $TESTS_FAILED -gt 0 ]; then echo -e "${RED}Failed: ${TESTS_FAILED}${NC}" echo "" echo -e "${RED}✗ Some tests failed${NC}" exit 1 else echo -e "${RED}Failed: ${TESTS_FAILED}${NC}" echo "" echo -e "${GREEN}✓ All tests passed successfully!${NC}" echo "" echo -e "${GREEN}Git setup is fully functional via HTTPS${NC}" exit 0 fi } # Run main function main