Delgus
@Delgus

Как написать тест чтобы защититься от race condition?

Допустим есть у меня некая библиотека
package v1

var balance int

//Deposit ...
func Deposit(amount int) {
	balance = balance + amount
}

//Balance ...
func Balance() int {
	return balance
}

func setBalance(amount int) {
	balance = amount
}

Здесь возможно состояние гонки, если вызвать функцию в разных горутинах.

Имеет ли право на жизнь такой тест кейс?
func TestRaceDeposit(t *testing.T) {
	setBalance(0)
	ch := make(chan struct{})
	go func() {
		Deposit(10)
		ch <- struct{}{}
	}()
	Deposit(10)
	<-ch
	if Balance() != 20 {
		t.Errorf("unexpected balance: value - %d expect 20", Balance())
	}
}

Чтобы при запуске тестов с флагом -race иметь возможность отлавливать состояние гонки
  • Вопрос задан
  • 283 просмотра
Решения вопроса 2
@ghostiam
На Go писатель, серверов пинатель.
Я бы написал так
func TestRaceDeposit(t *testing.T) {
	setBalance(0)

	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			Deposit(10)
			wg.Done()
		}()
	}

	wg.Wait()

	expect := 100
	got := Balance()
	if got != expect {
		t.Errorf("unexpected balance: value - %d expect %d", got, expect)
	}
}
Ответ написан
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
Race detector достаточно умный, не требует ничего военно-специфического вроде sync.WaitGroup. Чтобы диагностировать race достаточно просто обратиться к незащищенным данным асинхронно.
func TestRaceDeposit(t *testing.T) {
  setBalance(0)
  go Deposit(10)   //Просто этого вызова уже достаточно
  Deposit(10)
  if Balance() != 20 {
    t.Errorf("unexpected balance: value - %d expect 20", Balance())
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы