2012年2月12日日曜日

HTTPリクエストパラメータを抽出する

テストケースのないシステムをメンテンナンスをすることもあると思います。 HTTPで提供するAPIのテストケースを作成しなければならない場合は、 とにかくログを投げまくってテストするなどの方法が有効だったりするんですが、 (まあそもそもテストケースがないシステムについてのツッコミは受け付けません) ログから有効なテストケースを抽出するために、 リクエストパラメータの組み合わせによるURLの抽出なんかが一つの案です。 ということでログからリクエストパラメータの抽出を行うスクリプトをざっくり書いてみました。

import sys
from collections import defaultdict
from furl import furl

sampling_urls = defaultdict(dict)

for line in sys.stdin:
    url = line.strip()
    f = furl(url)
    param_keys = tuple(sorted(f.args.keys()))
    param_combination = sampling_urls[str(f.path)]
    if param_keys not in param_combination:
        param_combination[param_keys] = url

for path, param_combination in sampling_urls.items():
    for combination, sample_url in param_combination.items():
        print path, combination, sample_url

インプットログ
http://xxx/api?param1=a&param2=a
http://xxx/api?param1=b&param2=b
http://xxx/api?param1=c&param2=c&param3=c
http://xxx/api?param1=d&param2=d&param3=c
http://xxx/api?param1=e&param2=d&param4=d
http://xxx/api2?param1=e&param2=d&param4=d
http://xxx/api3?param1=e&param2=d&param4=d
実行結果
$ python sampling.py < input 
/api2 ('param1', 'param2', 'param4') http://xxx/api2?param1=e&param2=d&param4=d
/api ('param1', 'param2', 'param3') http://xxx/api?param1=c&param2=c&param3=c
/api ('param1', 'param2', 'param4') http://xxx/api?param1=e&param2=d&param4=d
/api ('param1', 'param2') http://xxx/api?param1=a&param2=a
/api3 ('param1', 'param2', 'param4') http://xxx/api3?param1=e&param2=d&param4=d
前に記事に書いたfurlというurlパーサーを利用しています。 itertools.combinationsとかを使わないとできないかと思いましたが、 tupleを辞書のキーにすることで簡単にできました。 valueが空の時の処理などは必要に応じて作成する必要がありますが、 それなりに有効そうです。