2.6.17

Golang: Simulating test timeouts w/ channels.

Golang doesn't have a test timeout feature that you might be used to in languages like Java, i.e.
@Test(timeout=1000)
Instead, you can do something equivalent using channels:

The strategy is as follows:

1) Create a channel, call it testResult or similar.  

2) Create another channel, which represents a measurement you are planning to take in the test.  For example, requestTime.  You will wait on this channel get written to, and at some point, after n writes, you will signal to the testResult.

3) When your test is completed, and the critera for the first channel (the thing you are measuring) is completed, and you have decided wether or not the test passed or failed, send 'true' or 'false' to testResult.

4) On the receiving end of your channels: You will want a for { select { ... } } loop, which waits for a write to testResult.  Once the write is received, this select loop will tear down any resources your unit test has created.

Excuse the syntax errors below, blogger hates the fonts I paste.


+ select {
+ // shutdown hook for the unit test.
+ case <- span="">testResult:
+ log.Println("Test result obtained. Exiting inifinte request time simulator.")
+ return
+ // simulate 'the hub' being down.
+ default:
+ log.Println("Test still running.",time.Now())
+ time.Sleep(1 * time.Second)
+ }

5) At the END of your unit test, the final thing you will have, will be a { for { select { ... } } loop which selects on two things time.After(testTimeout), and requestTime.   If requestTime has been tripped enough times that you are happy, RETURN.  If time.After trips, write false to testResult, and RETURN.


+ select {
+ case <- span="">requestCompleted:
+ testResult <- span=""> true
+ return
+ case <- span="">time.After(totalAllowedTime):
+ testResult <- span=""> false
+ t.Fail()
+ return
+ }
+ }
Now, you don't have to google for 'golang test timeout' anymore :).  

2 comments: