Testy - jak wywołać wielokrotnie tę samą metodę w tym samym czasie

0

Cześć,

Potrzebuję napisać test, który będzie stukać mój endpoint wielokrotnie w tym samym czasie - udało mi się to osiągnąć ręcznie poprzez curl & curl & curl ( asynchronicznie atakuje mój endpoint ) natomiast nie potrafię sobie poradzić z napisaniem testu, który zrobi to samo.
Chodzi o to, że uderzając requestami po kolei wszystko jest ok, natomiast kiedy endpoint bombardowany jest przez kilka requestów w krótkim czasie leci błąd Optimistic locking, poneiważ requesty próbują modyfikować tę samą encje.
Udało mi się to naprawić ( weryfikując curlami ) natomiast nie potrafię wykazać to w testach, wszelkie próby tworzenia wielu wątków i wywoływania jednocześnie metody świecą na zielono.
Prośba o porady, wskazówki.

0

to

jatylkonachwile napisał(a):

Udało mi się to naprawić ( weryfikując curlami )

i to

natomiast nie potrafię wykazać to w testach, wszelkie próby tworzenia wielu wątków i wywoływania jednocześnie metody świecą na zielono.

= ?????

1

Zróbmy 3 kroki wstecz :) co chcesz przetestować tym junitem?

1

I trzeba doprecyzować jaka to technologia.

1

Albo w intelliju zaznaczasz ile razy ma sie wykonac test, w junicie jest @RepeatedTest. Od biedy pętla

0

Możesz spawnować wątki w teście, ale musisz je jakoś sprytnie zsynchronizować, tak zeby się odpaliły wszystkie "na raz". Inaczej pewnie odpalają sie mimo wszystko jeden po drugim :)

0

Moze tempus fugit?
https://www.baeldung.com/java-testing-multithreaded

Fun fact: ww link to pierwszy wynik dla hasla java stupid annotations thread

1
Shalom napisał(a):

Możesz spawnować wątki w teście, ale musisz je jakoś sprytnie zsynchronizować, tak zeby się odpaliły wszystkie "na raz". Inaczej pewnie odpalają sie mimo wszystko jeden po drugim :)

IMO tak czy siak autor, mówiąc w tym samym czasie ma na myśli w bardzo krótkim odstępie czasowym pomiędzy sobą, czyli właśnie set wątków i potem dla każdego Thread::start i będzie to o co chodziło.

Tak czy siak, co do tematu - skoro masz zaimplementowany optimistic locking, no to jak kilku będzie próbowało zrobić update tej samej wersji, no to poleci ten OptimisticLockException, tak to działa ;D user musi pobrać nową wersję encji i jeszcze raz zrobić update. W ostateczności, jeśli chcesz, można próbować w pętli, try / catch i podbijać wersję w przypadku exceptiona, ale wtedy cała ta zabawa traci zupełnie swój sens.

EDIT:
Tak sobie pomyślałem nad pewnym casem, gdzie nie chcemy optimist locka - np w bazie filmów, dany film na jakąś średnią ocen i 100 userów w tej samej chwili chce dać swoją ocenę (która zupdejtuje średnią) - wóczas dany user raczej ma wywalone na to, czy wmiędzyczasie ktoś inny zagłosował na 1 czy na 5....
Tutaj kilka artykułów co do samego optimistic locka:
https://vladmihalcea.com/an-entity-modeling-strategy-for-scaling-optimistic-locking/
https://vladmihalcea.com/how-to-prevent-optimisticlockexception-using-hibernate-versionless-optimistic-locking/
https://vladmihalcea.com/bulk-update-optimistic-locking/

2

@jatylkonachwile: dowiemy się co chcesz przetestować? Co ta apka/endpoint robi biznesowo?

1
  1. odpal server
  2. utwórz a = CountdownLatch(1)
  3. odpal 100(lub więcej) wątków (client http), z priorytetem wysokim
  4. w kazdym wątku przygotuj co trzeba do odpalenia http ... ale zanim to zrobisz zatrzymaj się na a.await()
  5. w głównym wątku poczekaj chwile.. a potem walnij a.countDown()
  6. zrób join na wątkach i sprawdź czy wszystkie dostały ok.( można to też zrobić ExecutorServisem) ale imo gółe wątki + atomicBoolean na errora będzie łatwiejsze.

Kluczowe pytanie - to czy jak leci ten optimistic lock to dostajesz error na http?

Ogólnie to rzeźba i nie wiadomo czy dostaniesz error wystarczająco często. Ale takie testy są z natury niedeterministyczne. Można dobrać parametry tak, żeby na konkretnej maszynie często się wywalało.
Taki test dałoby się zrobić deterministycznie, gdyby countdown latch umieścić np. w repository (stworzyć testowe repository które wrapuje normalne repo, ale dodaje oczekiwanie na warunek).

1 użytkowników online, w tym zalogowanych: 0, gości: 1