philosophers_prep/testers/README.md

284 lines
7.6 KiB
Markdown

# 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! 🍀