10cd9f4ecSchristos#!/usr/bin/env python 2f42d8de7Schristos# 3f42d8de7Schristos# Test for pyunbound lookup. 4f42d8de7Schristos# BSD licensed. 5f42d8de7Schristos# 6f42d8de7Schristosimport sys 7f42d8de7Schristosimport time 8f42d8de7Schristos 90cd9f4ecSchristosimport unbound 100cd9f4ecSchristos 11f42d8de7Schristosqname = "www.example.com" 12*7a540f2bSchristosqname2 = "www2.example.com" 13f42d8de7Schristosqtype = unbound.RR_TYPE_A 14f42d8de7Schristosqclass = unbound.RR_CLASS_IN 15f42d8de7Schristos 16*7a540f2bSchristos 17f42d8de7Schristosdef create_context(config_file="ub.lookup.conf", asyncflag=False): 18f42d8de7Schristos """ 19f42d8de7Schristos Create an unbound context to use for testing. 20f42d8de7Schristos 21f42d8de7Schristos """ 220cd9f4ecSchristos ctx = unbound.ub_ctx() 23f42d8de7Schristos status = ctx.config(config_file) 240cd9f4ecSchristos if status != 0: 25f42d8de7Schristos print("read config failed with status: {}".format(status)) 26f42d8de7Schristos sys.exit(1) 27f42d8de7Schristos ctx.set_async(asyncflag) 28f42d8de7Schristos return ctx 290cd9f4ecSchristos 300cd9f4ecSchristos 31f42d8de7Schristosdef callback(data, status, result): 32f42d8de7Schristos """ 33f42d8de7Schristos Callback for background workers. 34f42d8de7Schristos 35f42d8de7Schristos """ 36f42d8de7Schristos if status == 0: 37f42d8de7Schristos data['rcode'] = result.rcode 38f42d8de7Schristos data['secure'] = result.secure 39f42d8de7Schristos if result.havedata: 40f42d8de7Schristos data['data'] = result.data 41f42d8de7Schristos data['was_ratelimited'] = result.was_ratelimited 42f42d8de7Schristos data['done'] = True 43f42d8de7Schristos 44f42d8de7Schristos 45f42d8de7Schristosdef test_resolve(ctx): 46f42d8de7Schristos """ 47f42d8de7Schristos Test resolving a domain with a foreground worker. 48f42d8de7Schristos 49f42d8de7Schristos """ 50f42d8de7Schristos status, result = ctx.resolve(qname, qtype, qclass) 510cd9f4ecSchristos if status == 0 and result.havedata: 52f42d8de7Schristos print("Resolve: {}".format(result.data.address_list)) 530cd9f4ecSchristos else: 54f42d8de7Schristos print("Failed resolve with: {}".format(status)) 550cd9f4ecSchristos 560cd9f4ecSchristos 57f42d8de7Schristosdef test_async_resolve(ctx): 58f42d8de7Schristos """ 59f42d8de7Schristos Test resolving a domain with a background worker. 60f42d8de7Schristos 61f42d8de7Schristos """ 62f42d8de7Schristos cb_data = dict(done=False) 63f42d8de7Schristos retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass) 64f42d8de7Schristos while retval == 0 and not cb_data['done']: 65f42d8de7Schristos time.sleep(0.1) 66f42d8de7Schristos retval = ctx.process() 67f42d8de7Schristos 68f42d8de7Schristos if cb_data.get('data'): 69f42d8de7Schristos print("Async resolve: {}".format(cb_data['data'].address_list)) 70f42d8de7Schristos else: 71f42d8de7Schristos print("Failed async resolve with: {}".format(retval)) 72f42d8de7Schristos 73f42d8de7Schristos 74f42d8de7Schristosdef test_ratelimit_bg_on(ctx): 75f42d8de7Schristos """ 76f42d8de7Schristos Test resolving a ratelimited domain with a background worker. 77f42d8de7Schristos 78f42d8de7Schristos """ 79f42d8de7Schristos ctx.set_option("ratelimit:", "1") 80f42d8de7Schristos ctx.set_option("ratelimit-factor:", "0") 81*7a540f2bSchristos total_runs = 6 82*7a540f2bSchristos success_threshold = 4 # 2/3*total_runs 83*7a540f2bSchristos successes = 0 84*7a540f2bSchristos for i in range(total_runs): 85f42d8de7Schristos cb_data = dict(done=False) 86*7a540f2bSchristos cb_data2 = dict(done=False) 87f42d8de7Schristos retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass) 88*7a540f2bSchristos retval, async_id = ctx.resolve_async(qname2, cb_data2, callback, qtype, qclass) 89*7a540f2bSchristos 90*7a540f2bSchristos while retval == 0 and not (cb_data['done'] and cb_data['done']): 91f42d8de7Schristos time.sleep(0.1) 92f42d8de7Schristos retval = ctx.process() 93f42d8de7Schristos 94*7a540f2bSchristos if bool(cb_data.get('was_ratelimited')) ^ bool(cb_data2.get('was_ratelimited')): 95*7a540f2bSchristos successes += 1 96*7a540f2bSchristos if successes >= success_threshold: 97*7a540f2bSchristos break 98*7a540f2bSchristos time.sleep(1) 99*7a540f2bSchristos if successes >= success_threshold: 100f42d8de7Schristos print("Ratelimit-bg-on: pass") 101f42d8de7Schristos else: 102*7a540f2bSchristos print("Failed ratelimit-bg-on") 103f42d8de7Schristos 104f42d8de7Schristos 105f42d8de7Schristostest_resolve(create_context()) 106f42d8de7Schristostest_async_resolve(create_context(asyncflag=True)) 107f42d8de7Schristostest_ratelimit_bg_on(create_context(asyncflag=True)) 108f42d8de7Schristos 109f42d8de7Schristossys.exit(0) 110