# Philosophers Preparation - Test Suite Este diretório contém testers automáticos para todos os exercícios preparatórios do projeto Philosophers da 42. ## 📋 Estrutura Cada exercício tem seu próprio script de teste: 1. `test_1_thread_basics.sh` - Testa criação básica de threads 2. `test_2_mutex_basics.sh` - Testa proteção de variáveis com mutex 3. `test_3_precise_timing.sh` - Testa funções de timing preciso 4. `test_4_state_monitor.sh` - Testa monitoramento de estados 5. `test_5_producer_consumer.sh` - Testa padrão produtor-consumidor 6. `test_6_deadlock_demo.sh` - Testa demonstração e solução de deadlock 7. `test_7_limited_resources.sh` - Testa recursos limitados (semáforos) 8. `test_8_simple_philosophers.sh` - Testa filósofos simplificado 9. `test_9_death_monitor.sh` - Testa sistema de detecção de morte 10. `test_10_philosophers_args.sh` - Testa filósofos completo com argumentos 11. `test_11_race_detector.sh` - Testa detecção de data races 12. `test_12_philosophers_bonus.sh` - Testa versão bonus com processos ## 🚀 Como Usar ### Testar um exercício específico: ```bash cd /home/ruiferna/Downloads/philosophers_prep chmod +x testers/*.sh # Tornar todos os scripts executáveis # Executar teste de um exercício específico bash testers/test_1_thread_basics.sh # Ou usando o runner principal bash testers/run_all_tests.sh 1 ``` ### Testar todos os exercícios: ```bash bash testers/run_all_tests.sh ``` ## 📝 Pré-requisitos ### Obrigatório: - `gcc` ou `cc` - Para compilar - `bash` - Para executar os scripts - Biblioteca pthread ### Opcional (para testes completos): - `valgrind` - Para detectar memory leaks - `gcc` com suporte a `-fsanitize=thread` - Para detectar data races - `helgrind` (parte do valgrind) - Para análise avançada de threading ### Instalar ferramentas (Ubuntu/Debian): ```bash sudo apt-get update sudo apt-get install gcc valgrind build-essential ``` ## 🎯 O que cada teste verifica ### Testes Comuns (na maioria dos exercícios): - ✅ **Execução básica** - Programa roda sem crash - ✅ **Funcionalidade** - Comportamento esperado - ✅ **Output correto** - Mensagens e formato - ✅ **Memory leaks** - Usando valgrind - ✅ **Data races** - Usando thread sanitizer/helgrind - ✅ **Edge cases** - Casos limite e argumentos inválidos ### Testes Específicos por Exercício: #### 1. Thread Basics - Criação de 2 threads - Mensagens corretas de cada thread - Quantidade correta de mensagens - Join das threads #### 2. Mutex Basics - Valor final do contador = 4000 - Consistência através de múltiplas execuções - Tempo de execução reportado - Ausência de race conditions #### 3. Precise Timing - Sleep de 100ms com precisão ±5ms - Consistência do timing - Formato do output #### 4. State Monitor - 3 workers + 1 monitor - Transições de estados (WORKING, RESTING, THINKING) - Timestamps - Detecção de workers travados #### 5. Producer-Consumer - 2 produtores + 2 consumidores - Todos os items (1-100) produzidos e consumidos - Sem duplicação de consumo - Buffer limitado funcionando #### 6. Deadlock Demo - Modo 0: Demonstra deadlock (trava) - Modo 1: Solução funciona (completa) - Ambas as threads completam no modo solução #### 7. Limited Resources - 10 estudantes, 3 computadores - Máximo 3 usuários simultâneos - Todos eventualmente usam o recurso - Sem starvation #### 8. Simple Philosophers - 3 filósofos, 3 garfos - Programa roda por ~10 segundos - Todos comem múltiplas vezes - Sem deadlock - Sem mortes #### 9. Death Monitor - 4 workers + monitor - Detecção de "morte" (inatividade >3s) - Atualização de last_activity_time - Monitor verifica a cada 100ms #### 10. Philosophers Args (Completo) - Parsing de argumentos correto - Caso básico: ninguém morre - Detecção de morte quando esperado - Limite de refeições funciona - Filósofo sozinho morre - Timestamps crescentes #### 11. Race Detector - Múltiplas iterações/estratégias testadas - Estatísticas reportadas - Testes com helgrind/drd - Edge cases (ímpar/par, timing apertado) #### 12. Philosophers Bonus - Usa fork() (processos, não threads) - Usa semáforos POSIX - Cleanup de semáforos - Sem processos zombie - Signal handling ## 🔍 Interpretando Resultados ### Símbolos: - ✓ **PASSED** (verde) - Teste passou - ✗ **FAILED** (vermelho) - Teste falhou - ⚠ **WARNING/PARTIAL** (amarelo) - Passou com avisos - ⊘ **SKIPPED** (amarelo) - Teste não executado (ferramenta faltando) ### Exemplo de saída: ``` ======================================== Testing: thread_basics ======================================== Test 1: Basic execution (1 message)... ✓ PASSED Test 2: Multiple messages (5)... ✓ PASSED Test 3: Large number (10)... ✓ PASSED Test 4: Memory leak check... ✓ PASSED ======================================== Results: 4 passed, 0 failed ======================================== ``` ## 🐛 Debugging ### Se um teste falha: 1. **Veja o output detalhado**: ```bash bash testers/test_X_exercise.sh 2>&1 | tee test_output.txt ``` 2. **Execute seu programa manualmente**: ```bash ./exercise_name [args] ``` 3. **Use valgrind para memory leaks**: ```bash valgrind --leak-check=full ./exercise_name ``` 4. **Use helgrind para data races**: ```bash valgrind --tool=helgrind ./exercise_name ``` 5. **Use thread sanitizer**: ```bash gcc -fsanitize=thread -g exercise.c -pthread -o exercise_tsan ./exercise_tsan ``` ## 📚 Dicas ### Compilação: Sempre compile com flags de warning: ```bash gcc -Wall -Wextra -Werror -pthread exercise.c -o exercise ``` ### Para o projeto real Philosophers: - Death detection deve ser < 10ms - Nenhum data race é aceitável (nota 0) - Memory leaks = pontos perdidos - Teste com números ímpares e pares de filósofos - Teste com `time_to_die` muito próximo de `time_to_eat` ### Casos importantes para testar: ```bash ./philo 1 800 200 200 # Deve morrer ./philo 4 410 200 200 # Caso difícil ./philo 4 310 200 100 # Muito apertado ./philo 5 800 200 200 # Número ímpar ./philo 5 800 200 200 7 # Com limite de refeições ``` ## 🔧 Troubleshooting ### "Permission denied": ```bash chmod +x testers/*.sh ``` ### "Valgrind not found": ```bash sudo apt-get install valgrind ``` ### "Thread sanitizer não funciona": ```bash # Verifique versão do gcc gcc --version # Precisa >= 4.8 # Tente com g++ se gcc não funcionar g++ -fsanitize=thread exercise.c -pthread -o exercise ``` ### Semáforos não limpam (bonus): ```bash # Liste semáforos ls /dev/shm/sem.* # Remova manualmente rm /dev/shm/sem.* ``` ## 📖 Recursos Adicionais - [Pthread Tutorial](https://computing.llnl.gov/tutorials/pthreads/) - [Valgrind Quick Start](https://valgrind.org/docs/manual/quick-start.html) - [Thread Sanitizer](https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual) - [Dining Philosophers Problem](https://en.wikipedia.org/wiki/Dining_philosophers_problem) ## 🤝 Contribuindo Se encontrar bugs nos testers ou quiser adicionar mais testes: 1. Reporte o issue 2. Submeta um pull request 3. Compartilhe com outros estudantes da 42 ## ✅ Checklist Final Antes de submeter o projeto Philosophers: - [ ] Todos os testers passam - [ ] Valgrind: 0 memory leaks - [ ] Helgrind: 0 data races - [ ] Nenhum filósofo morre quando não deveria - [ ] Death detection < 10ms após time_to_die - [ ] Funciona com 1, 2, 3, 4, 5+ filósofos - [ ] Funciona com timing apertado (310, 410ms) - [ ] Meal limit funciona corretamente - [ ] Código é norminette compliant - [ ] Makefile correto (all, clean, fclean, re) - [ ] Forbidden functions não são usadas Boa sorte! 🍀