176 lines
3.3 KiB
V
176 lines
3.3 KiB
V
module onecontext
|
|
|
|
import context
|
|
import time
|
|
|
|
fn eventually(ch chan int) bool {
|
|
mut background := context.background()
|
|
mut timeout, cancel := context.with_timeout(mut &background, 30 * time.millisecond)
|
|
defer {
|
|
cancel()
|
|
}
|
|
|
|
tdone := timeout.done()
|
|
select {
|
|
_ := <-ch {
|
|
return true
|
|
}
|
|
_ := <-tdone {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
struct Value {
|
|
val string
|
|
}
|
|
|
|
fn test_merge_nomilan() {
|
|
mut background := context.background()
|
|
foo := &Value{
|
|
val: 'foo'
|
|
}
|
|
mut value_ctx1 := context.with_value(background, 'foo', foo)
|
|
mut ctx1, cancel := context.with_cancel(mut &value_ctx1)
|
|
defer {
|
|
cancel()
|
|
}
|
|
|
|
bar := &Value{
|
|
val: 'bar'
|
|
}
|
|
mut value_ctx2 := context.with_value(background, 'bar', bar)
|
|
mut ctx2, _ := context.with_cancel(mut &value_ctx2)
|
|
|
|
mut ctx, cancel2 := merge(ctx1, ctx2)
|
|
|
|
if deadline := ctx.deadline() {
|
|
panic('this should never happen')
|
|
}
|
|
|
|
val1 := ctx.value('foo') or { panic('wrong value access for key `foo`') }
|
|
match val1 {
|
|
Value {
|
|
assert foo == val1
|
|
}
|
|
else {
|
|
assert false
|
|
}
|
|
}
|
|
|
|
val2 := ctx.value('bar') or { panic('wrong value access for key `bar`') }
|
|
match val2 {
|
|
Value {
|
|
assert bar == val2
|
|
}
|
|
else {
|
|
assert false
|
|
}
|
|
}
|
|
|
|
if _ := ctx.value('baz') {
|
|
panic('this should never happen')
|
|
}
|
|
|
|
assert !eventually(ctx.done())
|
|
assert ctx.err() is none
|
|
|
|
cancel2()
|
|
assert eventually(ctx.done())
|
|
assert ctx.err() is Error
|
|
}
|
|
|
|
fn test_merge_deadline_context_1() {
|
|
mut background := context.background()
|
|
mut ctx1, cancel := context.with_timeout(mut &background, time.second)
|
|
defer {
|
|
cancel()
|
|
}
|
|
ctx2 := context.background()
|
|
mut ctx, _ := merge(ctx1, ctx2)
|
|
|
|
if deadline := ctx.deadline() {
|
|
assert deadline.unix_time() != 0
|
|
} else {
|
|
panic('this should never happen')
|
|
}
|
|
}
|
|
|
|
fn test_merge_deadline_context_2() {
|
|
mut background := context.background()
|
|
ctx1 := context.background()
|
|
mut ctx2, cancel := context.with_timeout(mut &background, time.second)
|
|
defer {
|
|
cancel()
|
|
}
|
|
mut ctx, _ := merge(ctx1, ctx2)
|
|
|
|
if deadline := ctx.deadline() {
|
|
assert deadline.unix_time() != 0
|
|
} else {
|
|
panic('this should never happen')
|
|
}
|
|
}
|
|
|
|
fn test_merge_deadline_context_n() {
|
|
mut background := context.background()
|
|
ctx1 := context.background()
|
|
|
|
mut ctxs := []context.Context{cap: 21}
|
|
for i in 0 .. 10 {
|
|
ctxs << context.background()
|
|
}
|
|
mut ctx_n, _ := context.with_timeout(mut &background, time.second)
|
|
ctxs << ctx_n
|
|
|
|
for i in 0 .. 10 {
|
|
ctxs << context.background()
|
|
}
|
|
|
|
mut ctx, cancel := merge(ctx1, ...ctxs)
|
|
|
|
assert !eventually(ctx.done())
|
|
assert ctx.err() is none
|
|
cancel()
|
|
assert eventually(ctx.done())
|
|
assert ctx.err() is Error
|
|
}
|
|
|
|
fn test_merge_deadline_none() {
|
|
ctx1 := context.background()
|
|
ctx2 := context.background()
|
|
|
|
mut ctx, _ := merge(ctx1, ctx2)
|
|
|
|
if _ := ctx.deadline() {
|
|
panic('this should never happen')
|
|
}
|
|
}
|
|
|
|
fn test_merge_cancel_two() {
|
|
ctx1 := context.background()
|
|
ctx2 := context.background()
|
|
|
|
mut ctx, cancel := merge(ctx1, ctx2)
|
|
cancel()
|
|
|
|
assert eventually(ctx.done())
|
|
assert ctx.err() is Error
|
|
assert ctx.err().str() == 'canceled context'
|
|
}
|
|
|
|
fn test_merge_cancel_multiple() {
|
|
ctx1 := context.background()
|
|
ctx2 := context.background()
|
|
ctx3 := context.background()
|
|
|
|
mut ctx, cancel := merge(ctx1, ctx2, ctx3)
|
|
cancel()
|
|
|
|
assert eventually(ctx.done())
|
|
assert ctx.err() is Error
|
|
assert ctx.err().str() == 'canceled context'
|
|
}
|