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'
 | 
						|
}
 |