💯

PythonでLocustのUserClass生成を自動化してみる

2023/02/03に公開

動機

Locustを使い、数千ユーザ分のテストをしたかった。
ただ、サービスにはログイン機構があり、かつ1つのユーザごとに複数回のログイン処理をサーバ側で止めてしまう。よって、Locustの仕様?である、1ユーザ複製だと機能しなかった。
※Locustでpythonを数年ぶりに触りました、入門書ぶり。基本すべて脱noobくらい

解決法

ユーザを複数作成し、ユーザごとに1回ずつのログインにして負荷テストを行う。超力技。

Python理解(分かる人はスキップ)

sample.py
f = open('userClass.txt', 'w')
for x in range(5):
    print(f'''
    1
    2
    3
    4
    5
        \\
    {str(x).zfill(4)}
    {{aaa{str(x).zfill(4)}aaa}}
    ''')
f.close()
  1. 標準出力されても数万行など扱いに困るので、ファイル入力することに。今回は上書きで処理。
  2. for文、range(1..5)だと思ってた。違うんだね。あと:忘れてた、{}じゃないのかよ。endないし。
  3. 変数の入れ方。fをquoteの前にいれる、{}で囲む。
  4. 複数行の文字列をそのまま書く方法:quoteを3つで囲む。タブも改行もこれでそのまま認識される。便利だけどコメントアウトと同じって…まじで゚(゚´ω`゚)゚。ピー
  5. 変数にしたいところにゼロパディング( 0 padding )が必要だったので、zfill(桁数)を使いたかったのだけど、これstring型でしか使えないらしいからstr()で変更。
  6. jsonを使うので、{}が入っていておかしくなる。\でエスケープできないらしく、{{や}}と重ねることで文字列と認識されるよう。バックスラッシュはバックスラッシュでエスケープ

完成版

email形式はXXXXXXXX+NNNN@sample.comで統一している(NNNNは1234など)

generateUserClass.py
f = open('userClass.txt', 'w')
for x in range(1,5000):
    f.write(f'''
class Worker{str(x).zfill(4)}(HttpUser):
    fixed_count = 1  (->1ユーザにつき1つしか作られないように)
    tasks = [XXXXXXXX]
    wait_time = constant(2)

    def on_start(self):
	(略)
        response = self.client.post(
            url="https://"XXXXXXXX",
            data={{
                "user[email]": "XXXXXXXX+{str(x).zfill(4)}@sample.com",
                "user[password]": "password",
            }}
        )
	(略)
    ''')
f.close()

今後

この生成したコードで出力されたユーザクラスを別ファイルにするとimportが鬼の量になるし、かといってexec/evalあたりだとうまくいかなそうだし、、一旦実行ファイルの下にベタ貼りします()

Discussion