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から生成されているらしいけど、それがどこにあるのかもよくわからない。
まだまだ勉強が足りないようなので、まずは調べてみる。