Files
raspiblitz/test/bonus.postgresql-restore-locale.bats
2025-07-04 10:33:50 +02:00

233 lines
8.4 KiB
Bash

#!/usr/bin/env bats
# Test PostgreSQL restore functionality across locale changes
# This test uses the built-in backup/restore functionality of bonus.postgresql.sh
# to test locale compatibility when restoring databases
@test "Setup: Prepare en_GB environment and install PostgreSQL" {
# Ensure both locales are available
sudo sed -i '/^#en_GB.UTF-8 UTF-8/s/^#//' /etc/locale.gen
sudo sed -i '/^# en_GB.UTF-8 UTF-8/s/^# //' /etc/locale.gen
sudo sed -i '/^#en_US.UTF-8 UTF-8/s/^#//' /etc/locale.gen
sudo sed -i '/^# en_US.UTF-8 UTF-8/s/^# //' /etc/locale.gen
sudo locale-gen
# Set to en_GB initially
export LANG=en_GB.UTF-8
export LC_ALL=en_GB.UTF-8
# Install PostgreSQL
run ../home.admin/config.scripts/bonus.postgresql.sh on
[ "$status" -eq 0 ]
# Verify installation
run pg_lsclusters
[ "$status" -eq 0 ]
echo "$output" | grep -q "online"
}
@test "Create test database with en_GB locale and sample data" {
# Create database with en_GB locale
sudo -u postgres psql -c "CREATE DATABASE testdb_restore TEMPLATE template0 LC_CTYPE 'en_GB.UTF-8' LC_COLLATE 'en_GB.UTF-8' ENCODING 'UTF8';"
sudo -u postgres psql -c "CREATE USER testuser_restore WITH ENCRYPTED PASSWORD 'testpass123';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE testdb_restore TO testuser_restore;"
# Create sample data with locale-specific content
sudo -u postgres psql testdb_restore -c "
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
description TEXT,
created_date DATE DEFAULT CURRENT_DATE
);
INSERT INTO products (name, price, description) VALUES
('British Tea', 4.50, 'Premium Earl Grey - £4.50'),
('Scottish Whisky', 45.99, 'Single Malt - £45.99'),
('Welsh Cheese', 8.75, 'Caerphilly cheese - £8.75'),
('Irish Coffee', 6.25, 'Traditional recipe - £6.25');
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
product_id INTEGER REFERENCES products(id),
quantity INTEGER,
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
customer_notes TEXT
);
INSERT INTO orders (product_id, quantity, customer_notes) VALUES
(1, 2, 'Delivery to London postcode SW1A 1AA'),
(2, 1, 'Gift wrapping requested'),
(3, 3, 'Please check expiry date'),
(4, 1, 'Extra hot please');
"
# Verify data was created
record_count=$(sudo -u postgres psql testdb_restore -t -c "SELECT COUNT(*) FROM products;" | xargs)
[ "$record_count" -eq 4 ]
order_count=$(sudo -u postgres psql testdb_restore -t -c "SELECT COUNT(*) FROM orders;" | xargs)
[ "$order_count" -eq 4 ]
}
@test "Create backup using PostgreSQL script" {
# Use the built-in backup functionality
echo "# Creating backup using bonus.postgresql.sh"
run ../home.admin/config.scripts/bonus.postgresql.sh backup testdb_restore
[ "$status" -eq 0 ]
# Verify backup was created
backup_dir="/mnt/hdd/app-data/backup/testdb_restore"
[ -d "$backup_dir" ]
# Find the backup file (it has a timestamp in the name)
backup_file=$(ls -t $backup_dir/*.sql | head -n1)
[ -f "$backup_file" ]
# Verify backup contains our data
grep -q "British Tea" "$backup_file"
grep -q "£4.50" "$backup_file"
grep -q "SW1A 1AA" "$backup_file"
echo "# Backup created: $backup_file"
}
@test "Change system locale to en_US and reinstall PostgreSQL" {
# Change to en_US locale
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
echo -e "LANG=en_US.UTF-8\nLANGUAGE=en_US.UTF-8\nLC_ALL=en_US.UTF-8" | sudo tee /etc/default/locale > /dev/null
# Stop PostgreSQL
run ../home.admin/config.scripts/bonus.postgresql.sh off
[ "$status" -eq 0 ]
# Clean up
sudo pg_dropcluster 15 main --stop || true
sudo rm -rf /mnt/hdd/app-data/postgresql*
# Reinstall with en_US locale
run ../home.admin/config.scripts/bonus.postgresql.sh on
[ "$status" -eq 0 ]
# Verify new installation uses en_US
cluster_locale=$(sudo -u postgres psql -t -c "SHOW LC_COLLATE;" | xargs)
echo "# New cluster locale: $cluster_locale"
[[ "$cluster_locale" == *"en_US"* ]]
}
@test "Restore database using PostgreSQL script" {
# Use the built-in restore functionality
echo "# Restoring database using bonus.postgresql.sh"
run ../home.admin/config.scripts/bonus.postgresql.sh restore testdb_restore testuser_restore testpass123
[ "$status" -eq 0 ]
# Verify database was restored
run sudo -u postgres psql -l
echo "$output" | grep -q "testdb_restore"
# Verify user was created
run sudo -u postgres psql -c "\du"
echo "$output" | grep -q "testuser_restore"
}
@test "Verify data integrity after restore with locale change" {
# Check that all products were restored
product_count=$(sudo -u postgres psql testdb_restore -t -c "SELECT COUNT(*) FROM products;" | xargs)
echo "# Product count after restore: $product_count"
[ "$product_count" -eq 4 ]
# Check that all orders were restored
order_count=$(sudo -u postgres psql testdb_restore -t -c "SELECT COUNT(*) FROM orders;" | xargs)
echo "# Order count after restore: $order_count"
[ "$order_count" -eq 4 ]
# Verify specific data with currency symbols
run sudo -u postgres psql testdb_restore -t -c "SELECT description FROM products WHERE name = 'British Tea';"
echo "$output" | grep -q "£4.50"
# Verify postcode data (UK format)
run sudo -u postgres psql testdb_restore -t -c "SELECT customer_notes FROM orders WHERE id = 1;"
echo "$output" | grep -q "SW1A 1AA"
# Test that we can still query and sort data correctly
run sudo -u postgres psql testdb_restore -t -c "SELECT name FROM products ORDER BY price DESC LIMIT 1;"
echo "$output" | grep -q "Scottish Whisky"
# Test numeric operations work correctly
total_value=$(sudo -u postgres psql testdb_restore -t -c "SELECT SUM(price) FROM products;" | xargs)
echo "# Total product value: $total_value"
# Should be 4.50 + 45.99 + 8.75 + 6.25 = 65.49
[[ "$total_value" == "65.49" ]]
}
@test "Test database operations with mixed locale data" {
# Insert new data with US formatting
sudo -u postgres psql testdb_restore -c "
INSERT INTO products (name, price, description) VALUES
('American Coffee', 3.99, 'Regular blend - \$3.99'),
('New York Bagel', 2.50, 'Fresh baked - \$2.50');
INSERT INTO orders (product_id, quantity, customer_notes) VALUES
(5, 1, 'Delivery to ZIP code 10001'),
(6, 2, 'Extra cream cheese');
"
# Verify mixed data works correctly
total_products=$(sudo -u postgres psql testdb_restore -t -c "SELECT COUNT(*) FROM products;" | xargs)
[ "$total_products" -eq 6 ]
total_orders=$(sudo -u postgres psql testdb_restore -t -c "SELECT COUNT(*) FROM orders;" | xargs)
[ "$total_orders" -eq 6 ]
# Test that both UK and US currency symbols are preserved
run sudo -u postgres psql testdb_restore -t -c "SELECT description FROM products WHERE price < 5.00;"
echo "$output" | grep -q "£4.50" # UK pound
echo "$output" | grep -q "\$3.99" # US dollar
echo "$output" | grep -q "\$2.50" # US dollar
# Test sorting works with mixed locale data
run sudo -u postgres psql testdb_restore -t -c "SELECT name FROM products ORDER BY name;"
[ "$?" -eq 0 ]
echo "# Mixed locale data test completed successfully"
}
@test "Test user authentication and permissions" {
# Test that the restored user can connect and access data
run sudo -u postgres psql -d testdb_restore -U testuser_restore -c "SELECT COUNT(*) FROM products;"
[ "$?" -eq 0 ]
# Test that user has proper permissions
sudo -u postgres psql testdb_restore -c "
GRANT SELECT, INSERT, UPDATE, DELETE ON products TO testuser_restore;
GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO testuser_restore;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO testuser_restore;
"
# Test insert permission
run sudo -u postgres psql -d testdb_restore -U testuser_restore -c "
INSERT INTO products (name, price, description) VALUES ('Test Product', 1.00, 'Test');
"
[ "$?" -eq 0 ]
echo "# User authentication and permissions test completed"
}
@test "Cleanup: Remove test data and PostgreSQL" {
# Stop PostgreSQL
run ../home.admin/config.scripts/bonus.postgresql.sh off
[ "$status" -eq 0 ]
# Clean up clusters
sudo pg_dropcluster 15 main --stop || true
sudo pg_dropcluster 13 main --stop || true
sudo rm -rf /mnt/hdd/app-data/postgresql*
# Clean up backup directory
sudo rm -rf /mnt/hdd/app-data/backup/testdb_restore
echo "# Cleanup completed successfully"
}