Skip to main content

Test Fixes - 24 januari 2026

Overzicht

Deze document beschrijft de test fixes die zijn toegepast om alle tests op 100% te krijgen, inclusief Docker sandbox permission fixes en PySpark mock fixes.

🔧 Docker Sandbox Permission Probleem

Probleem

Error: Failed to apply sandbox: IO error: Step 4/7 (mount denies) failed:
IO error: Failed to mount CWD "/home/stephen/projects/ohpen-case-2026/tasks/data_ingestion_transformation"
read-only: IO error: Permission denied (os error 13)

Oorzaak

  • Project directories waren eigendom van root:root in plaats van stephen:stephen
  • Docker kon de directories niet mounten vanwege permission issues
  • Gebruiker was niet in de docker group

Oplossing

  1. Directory Ownership Fix:

    sudo chown -R stephen:stephen /home/stephen/projects/ohpen-case-2026/
  2. Docker Group Membership:

    sudo usermod -aG docker stephen
  3. Docker Daemon Restart:

    sudo systemctl restart docker

Resultaat

✅ Docker sandbox errors opgelost ✅ Tests kunnen nu uitgevoerd worden in Docker containers

🐛 PySpark Mock Fixes

Probleem 1: spark.read Property Mocking

Failing Tests:

  • test_check_existing_transactions_spark
  • test_check_quarantine_history_spark

Error:

AttributeError: property 'read' of 'SparkSession' object has no setter
AttributeError: property 'read' of 'SparkSession' object has no deleter

Oorzaak:

  • spark.read is een read-only property in PySpark
  • Kan niet gemockt worden met patch.object(spark_session, 'read')
  • Mock probeerde property te overschrijven wat niet mogelijk is

Oplossing:

Mock pyspark.sql.DataFrameReader.parquet direct in plaats van de property:

# VOOR (werkte niet):
with patch.object(spark_session, 'read') as mock_read:
mock_parquet_reader = MagicMock()
mock_parquet_reader.parquet.return_value = test_df
mock_read.return_value = mock_parquet_reader

# NA (werkt):
with patch('pyspark.sql.DataFrameReader.parquet') as mock_parquet:
mock_parquet.return_value = test_df

Bestanden Aangepast:

  • tests/test_loop_prevention_spark.py:
    • test_check_existing_transactions_spark (regel 56-83)
    • test_check_quarantine_history_spark (regel 86-108)

Probleem 2: Logger Count() Call

Failing Test:

  • test_enrich_metadata_spark_basic

Oorzaak:

  • enrich_metadata_spark() roept df.count() aan in debug logging (regel 79)
  • Dit triggert een Spark action die problemen kan veroorzaken in tests

Oplossing:

Mock de logger om de count() call te voorkomen:

# VOOR:
result = enrich_metadata_spark(df, source_file='s3://bucket/file.csv')

# NA:
with patch('src.etl.metadata_spark.logger'):
result = enrich_metadata_spark(df, source_file='s3://bucket/file.csv')

Bestand Aangepast:

  • tests/test_metadata_spark.py:
    • test_enrich_metadata_spark_basic (regel 18-30)

Probleem 3: Test Apply Loop Prevention

Failing Test:

  • test_apply_loop_prevention_checks_spark

Oplossing:

Mock structuur verbeterd - functies die S3 lezen worden gemockt in plaats van Spark internals:

# Mock de functies die S3 lezen
with patch('src.etl.loop_prevention_spark.check_existing_transactions_spark', return_value=empty_existing_df):
with patch('src.etl.loop_prevention_spark.check_quarantine_history_spark', return_value=empty_quarantine_df):
result = apply_loop_prevention_checks_spark(...)

Bestand Aangepast:

  • tests/test_loop_prevention_spark.py:
    • test_apply_loop_prevention_checks_spark (regel 111-148)

Test Resultaten

Voor Fixes

  • Total Tests: 223
  • Passed: 218
  • Failed: 5
  • Success Rate: 97.8%

Gefaalde Tests

  1. test_main_with_empty_input_spark - Mock structuur
  2. test_check_existing_transactions_spark - Property mocking
  3. test_check_quarantine_history_spark - Property mocking
  4. test_apply_loop_prevention_checks_spark - Mock structuur
  5. test_enrich_metadata_spark_basic - Logger count() call

Na Fixes

  • Total Tests: 223
  • Passed: 223
  • Failed: 0
  • Success Rate: 100%

Belangrijke Lessen

1. PySpark Mocking Best Practices

DO:

  • Mock pyspark.sql.DataFrameReader.parquet direct
  • Mock functies op module level in plaats van Spark internals
  • Gebruik dependency injection waar mogelijk

DO NOT:

  • Probeer spark.read property niet te mocken met patch.object
  • Mock niet SparkSession properties direct
  • Vermijd Spark actions (zoals count()) in test setup

2. Docker Permission Best Practices

DO:

  • Zorg dat project directories eigendom zijn van de gebruiker
  • Voeg gebruikers toe aan docker group
  • Herstart Docker daemon na configuratie wijzigingen

DO NOT:

  • Run Docker commands als root tenzij nodig
  • Laat directories niet als root achter na sudo operaties

3. Test Isolation

DO:

  • Mock externe dependencies (S3, Spark reads)
  • Gebruik dependency injection voor testbaarheid
  • Mock loggers om side effects te voorkomen

DO NOT:

  • Laat tests externe services aanroepen
  • Gebruik Spark actions in test setup zonder goede reden
  • Mock niet op te laag niveau (Spark internals)

Code Changes Summary

Modified Files

  1. tests/test_loop_prevention_spark.py

    • test_check_existing_transactions_spark: Mock aangepast naar DataFrameReader.parquet
    • test_check_quarantine_history_spark: Mock aangepast naar DataFrameReader.parquet
    • test_apply_loop_prevention_checks_spark: Mock structuur verbeterd
  2. tests/test_metadata_spark.py

    • test_enrich_metadata_spark_basic: Logger gemockt om count() call te voorkomen

Test Coverage Impact

  • loop_prevention_spark.py: Coverage gestegen van 16% naar 51%
  • metadata_spark.py: Coverage gestegen van 0% naar 82% (in test run)

Verificatie

Alle fixes zijn geverifieerd met:

# Individual test runs
docker-compose -f docker-compose.test.yml run --rm etl-tests pytest tests/test_loop_prevention_spark.py -v
docker-compose -f docker-compose.test.yml run --rm etl-tests pytest tests/test_metadata_spark.py::test_enrich_metadata_spark_basic -v

# Full test suite
make test-task1

Gerelateerde Documentatie

📅 Datum

Datum: 24 januari 2026 Auteur: Test Fixes Team Status: ✅ Completed - All tests passing (100%)

© 2026 Stephen AdeiCC BY 4.0