mocker.patchではまってわかったimportの仕組み
mocker.patchで関数の返り値を指定したかったんだけど、うまくいかずはまった。調べてたらimportが正しく理解できていないことがわかったので、メモ。
コード
utils.py(モック化したいもの)
def utilA(): return "returnA"
sample.py(テストしたいもの)
from utils import * def methodA(): str = utilA() return str
test_sample.py(テストコード)
from sample import * def test_A(mocker): mocker.patch('utils.utilA', return_value="mock_returnA") print(methodA())
うまくいかなかったこと
関数methodAのテストのため、utilAの戻り値をreturnAではなくmock_returnAにしたかった。
mocker.pathの第1引数はモジュール+オブジェクト名を書けば良い。今回モックにしたいのはutilsモジュールのutilA関数なので
utils.utilAであっているはず。
だけどテストを実行すると、
# pytest tests/testsample.py -s … tests/testsample.py returnA
と、returnAと出てきてしまった。これは通常通りutilAが実行されてしまっているのでモックが動いていない。なぜなのか。
うまくいった
いろいろ試した結果、mocker.pathの第1引数を
sample.utilA
と書けば、うまくutilAがモック化されることがわかった。
from sample import * def test_A(mocker): mocker.patch('sample.utilA', return_value="mock_returnA") print(methodA())
# pytest tests/testsample.py -s … tests/testsample.py mock_returnA
なぜなのか
ポイントはimportだった。自分めんどくさがりなので、自分のモジュールを読み込みたいときはfrom utils import *のようにアスタリスクを使ってインポートすることが多い。
これがどういうことなのかあまり深く考えたことなかったけど、sampleモジュールにutilsモジュールのオブジェクトを展開しているということのようだ。
なのでutilsモジュールのutilAではなくsampleモジュールのutilAを使っているイメージなようだ。
なのでmocker.patchにもmocker.patch('sample.utilA'と書かないと使っているutilAがモック化されない。
なお、PEP8ではこのアスタリスクでのインポートは推奨されていないらしい。
https://pep8-ja.readthedocs.io/ja/latest/#import
ワイルドカードを使った import (from
import *) は避けるべきです。なぜなら、どの名前が名前空間に存在しているかをわかりにくくし、コードの読み手や多くのツールを混乱させるからです。
sample.pyのimport文をimport utilsとし、utils.utilAを呼び出すコードにするなら、mocker.patch('sample.utilA'でうまくいく。
sample.py
from utils import def methodA(): str = utils.utilA() return str
from sample import * def test_A(mocker): mocker.patch('utils.utilA', return_value="mock_returnA") print(methodA())
# pytest tests/testsample.py -s … tests/testsample.py mock_returnA
IKEv1のpreshared-keyはどのように使われているのか
ふと、IKEv1のPreshared-key(事前共有鍵)認証で設定したキーは、ISAKMP SA作成時のパケットのどこに載っているのか気になった。(載っているもんだと思っていた。)
別件でstrongswanを使いそうな予感がしていたので、たいして書籍等調べもせず「GNS3のルータとstrongswan間でIPsec通信させて、ISAKMPのパケットを見ればわかるだろう」という安直な考えから、とりあえず両者の設定を行った。
各種バージョン
GNS3: 1.5.2 ゲストOS: Centos7.2 strongswan: 5.5.0
設定(Cisco)
show runの抜粋。
crypto isakmp policy 10 encr aes authentication pre-share group 5 crypto isakmp key cisco address 172.16.10.2 crypto isakmp keepalive 30 periodic crypto ipsec transform-set TS esp-aes esp-sha-hmac mode tunnel crypto map cmap 10 ipsec-isakmp set peer 172.16.10.2 set transform-set TS match address cryptoacl interface GigabitEthernet2/0 ip address 192.168.1.1 255.255.255.0 negotiation auto interface GigabitEthernet3/0 ip address 172.16.10.1 255.255.255.0 negotiation auto crypto map cmap ip route 192.168.2.0 255.255.255.0 172.16.10.2 ip access-list extended cryptoacl permit ip 192.168.1.0 0.0.0.255 192.168.2.0 0.0.0.255
設定(strongswan)
ipsec.conf
config setup
conn %default
ikelifetime=1440m
keylife=60m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
authby=secret
conn ciscoios
ikelifetime=1440m
left=172.16.10.2
leftsubnet=192.168.2.0/24
leftid=172.16.10.2
leftfirewall=yes
right=172.16.10.1
rightsubnet=192.168.1.0/24
rightid=172.16.10.1
auto=add
ike=aes128-sha1-modp1536
esp=aes128-sha1
ipsec.secrets
172.16.10.1 172.16.10.2 : PSK "cisco"
結果
Wiresharkでパケットを眺めていても全然わからなかった。ものの本によるとSKEYIDという鍵がpreshared-keyから生成されているらしいけど、それがどこにあるのかもよくわからない。
まだまだ勉強が足りないようなので、まずは調べてみる。
