1from collections import namedtuple 2from Queue import Queue 3from threading import Event, Thread 4 5import pytest 6 7from pyaxo import Axolotl 8 9 10def test_init_conversation(axolotl_a, axolotl_b, 11 a_identity_keys, b_identity_keys, 12 a_handshake_keys, b_handshake_keys, 13 a_ratchet_keys, b_ratchet_keys, 14 exchange): 15 conv_a = axolotl_a.init_conversation( 16 axolotl_b.name, 17 priv_identity_key=a_identity_keys.priv, 18 identity_key=a_identity_keys.pub, 19 priv_handshake_key=a_handshake_keys.priv, 20 other_identity_key=b_identity_keys.pub, 21 other_handshake_key=b_handshake_keys.pub, 22 priv_ratchet_key=a_ratchet_keys.priv, 23 ratchet_key=a_ratchet_keys.pub, 24 other_ratchet_key=b_ratchet_keys.pub) 25 26 conv_b = axolotl_b.init_conversation( 27 axolotl_a.name, 28 priv_identity_key=b_identity_keys.priv, 29 identity_key=b_identity_keys.pub, 30 priv_handshake_key=b_handshake_keys.priv, 31 other_identity_key=a_identity_keys.pub, 32 other_handshake_key=a_handshake_keys.pub, 33 priv_ratchet_key=b_ratchet_keys.priv, 34 ratchet_key=b_ratchet_keys.pub, 35 other_ratchet_key=a_ratchet_keys.pub) 36 37 exchange(conv_a, conv_b) 38 39 40def test_init_nonthreaded_conversations( 41 axolotl_a, axolotl_b, axolotl_c, 42 a_identity_keys, b_identity_keys, c_identity_keys, 43 a_handshake_keys, b_handshake_keys, c_handshake_keys, 44 a_ratchet_keys, b_ratchet_keys, c_ratchet_keys, 45 exchange): 46 conversations = initialize_conversations( 47 axolotl_a, a_identity_keys, a_handshake_keys, a_ratchet_keys, 48 axolotl_b, b_identity_keys, b_handshake_keys, b_ratchet_keys, 49 axolotl_c, c_identity_keys, c_handshake_keys, c_ratchet_keys) 50 51 exchange(conversations.ab, conversations.ba) 52 exchange(conversations.ac, conversations.ca) 53 exchange(conversations.bc, conversations.cb) 54 55 56def test_init_threaded_conversations( 57 threaded_axolotl_a, threaded_axolotl_b, threaded_axolotl_c, 58 a_identity_keys, b_identity_keys, c_identity_keys, 59 a_handshake_keys, b_handshake_keys, c_handshake_keys, 60 a_ratchet_keys, b_ratchet_keys, c_ratchet_keys, 61 exchange): 62 conversations = initialize_conversations( 63 threaded_axolotl_a, a_identity_keys, a_handshake_keys, a_ratchet_keys, 64 threaded_axolotl_b, b_identity_keys, b_handshake_keys, b_ratchet_keys, 65 threaded_axolotl_c, c_identity_keys, c_handshake_keys, c_ratchet_keys) 66 67 run_threaded_exchanges(exchange, conversations) 68 69 70def test_create_conversation(axolotl_a, axolotl_b, 71 a_identity_keys, b_identity_keys, 72 a_handshake_keys, b_handshake_keys, 73 a_ratchet_keys, b_ratchet_keys, 74 exchange): 75 mkey = 'masterkey' 76 77 conv_a = axolotl_a.create_conversation( 78 other_name=axolotl_b.name, 79 mkey=mkey, 80 mode=True, 81 priv_identity_key=a_identity_keys.priv, 82 identity_key=a_identity_keys.pub, 83 other_identity_key=b_identity_keys.pub, 84 other_ratchet_key=b_ratchet_keys.pub) 85 86 conv_b = axolotl_b.create_conversation( 87 other_name=axolotl_a.name, 88 mkey=mkey, 89 mode=False, 90 priv_identity_key=b_identity_keys.priv, 91 identity_key=b_identity_keys.pub, 92 other_identity_key=a_identity_keys.pub, 93 priv_ratchet_key=b_ratchet_keys.priv, 94 ratchet_key=b_ratchet_keys.pub) 95 96 exchange(conv_a, conv_b) 97 98 99def test_create_nonthreaded_conversations( 100 axolotl_a, axolotl_b, axolotl_c, 101 a_identity_keys, b_identity_keys, c_identity_keys, 102 a_handshake_keys, b_handshake_keys, c_handshake_keys, 103 a_ratchet_keys, b_ratchet_keys, c_ratchet_keys, 104 exchange): 105 mkey_ab = 'masterkey_ab' 106 mkey_ac = 'masterkey_ac' 107 mkey_bc = 'masterkey_bc' 108 109 conversations = create_conversations( 110 axolotl_a, a_identity_keys, a_handshake_keys, a_ratchet_keys, 111 axolotl_b, b_identity_keys, b_handshake_keys, b_ratchet_keys, 112 axolotl_c, c_identity_keys, c_handshake_keys, c_ratchet_keys, 113 mkey_ab, mkey_ac, mkey_bc) 114 115 exchange(conversations.ab, conversations.ba) 116 exchange(conversations.ac, conversations.ca) 117 exchange(conversations.bc, conversations.cb) 118 119 120def test_create_threaded_conversations( 121 threaded_axolotl_a, threaded_axolotl_b, threaded_axolotl_c, 122 a_identity_keys, b_identity_keys, c_identity_keys, 123 a_handshake_keys, b_handshake_keys, c_handshake_keys, 124 a_ratchet_keys, b_ratchet_keys, c_ratchet_keys, 125 exchange): 126 mkey_ab = 'masterkey_ab' 127 mkey_ac = 'masterkey_ac' 128 mkey_bc = 'masterkey_bc' 129 130 conversations = create_conversations( 131 threaded_axolotl_a, a_identity_keys, a_handshake_keys, a_ratchet_keys, 132 threaded_axolotl_b, b_identity_keys, b_handshake_keys, b_ratchet_keys, 133 threaded_axolotl_c, c_identity_keys, c_handshake_keys, c_ratchet_keys, 134 mkey_ab, mkey_ac, mkey_bc) 135 136 run_threaded_exchanges(exchange, conversations) 137 138 139@pytest.fixture() 140def threaded_axolotl_a(): 141 return Axolotl('Angie', dbpassphrase=None, nonthreaded_sql=False) 142 143 144@pytest.fixture() 145def threaded_axolotl_b(): 146 return Axolotl('Barb', dbpassphrase=None, nonthreaded_sql=False) 147 148 149@pytest.fixture() 150def threaded_axolotl_c(): 151 return Axolotl('Charlie', dbpassphrase=None, nonthreaded_sql=False) 152 153 154class ThreadedExchange(Thread): 155 def __init__(self, exchange, axolotl_x, axolotl_y, event, queue): 156 super(ThreadedExchange, self).__init__() 157 self.daemon = True 158 self.exchange = exchange 159 self.axolotl_x = axolotl_x 160 self.axolotl_y = axolotl_y 161 self.event = event 162 self.queue = queue 163 164 def run(self): 165 self.event.wait() 166 try: 167 self.exchange(self.axolotl_x, self.axolotl_y) 168 except AssertionError: 169 self.queue.put(False) 170 else: 171 self.queue.put(True) 172 173 174Conversations = namedtuple('Conversations', 'ab ac ba bc ca cb') 175 176 177def initialize_conversations( 178 axolotl_a, a_identity_keys, a_handshake_keys, a_ratchet_keys, 179 axolotl_b, b_identity_keys, b_handshake_keys, b_ratchet_keys, 180 axolotl_c, c_identity_keys, c_handshake_keys, c_ratchet_keys): 181 ab = axolotl_a.init_conversation( 182 other_name=axolotl_b.name, 183 priv_identity_key=a_identity_keys.priv, 184 identity_key=a_identity_keys.pub, 185 priv_handshake_key=a_handshake_keys.priv, 186 other_identity_key=b_identity_keys.pub, 187 other_handshake_key=b_handshake_keys.pub, 188 priv_ratchet_key=a_ratchet_keys.priv, 189 ratchet_key=a_ratchet_keys.pub, 190 other_ratchet_key=b_ratchet_keys.pub) 191 192 ac = axolotl_a.init_conversation( 193 other_name=axolotl_c.name, 194 priv_identity_key=a_identity_keys.priv, 195 identity_key=a_identity_keys.pub, 196 priv_handshake_key=a_handshake_keys.priv, 197 other_identity_key=c_identity_keys.pub, 198 other_handshake_key=c_handshake_keys.pub, 199 priv_ratchet_key=a_ratchet_keys.priv, 200 ratchet_key=a_ratchet_keys.pub, 201 other_ratchet_key=c_ratchet_keys.pub) 202 203 ba = axolotl_b.init_conversation( 204 other_name=axolotl_a.name, 205 priv_identity_key=b_identity_keys.priv, 206 identity_key=b_identity_keys.pub, 207 priv_handshake_key=b_handshake_keys.priv, 208 other_identity_key=a_identity_keys.pub, 209 other_handshake_key=a_handshake_keys.pub, 210 priv_ratchet_key=b_ratchet_keys.priv, 211 ratchet_key=b_ratchet_keys.pub, 212 other_ratchet_key=a_ratchet_keys.pub) 213 214 bc = axolotl_b.init_conversation( 215 other_name=axolotl_c.name, 216 priv_identity_key=b_identity_keys.priv, 217 identity_key=b_identity_keys.pub, 218 priv_handshake_key=b_handshake_keys.priv, 219 other_identity_key=c_identity_keys.pub, 220 other_handshake_key=c_handshake_keys.pub, 221 priv_ratchet_key=b_ratchet_keys.priv, 222 ratchet_key=b_ratchet_keys.pub, 223 other_ratchet_key=c_ratchet_keys.pub) 224 225 ca = axolotl_c.init_conversation( 226 other_name=axolotl_a.name, 227 priv_identity_key=c_identity_keys.priv, 228 identity_key=c_identity_keys.pub, 229 priv_handshake_key=c_handshake_keys.priv, 230 other_identity_key=a_identity_keys.pub, 231 other_handshake_key=a_handshake_keys.pub, 232 priv_ratchet_key=c_ratchet_keys.priv, 233 ratchet_key=b_ratchet_keys.pub, 234 other_ratchet_key=a_ratchet_keys.pub) 235 236 cb = axolotl_c.init_conversation( 237 other_name=axolotl_b.name, 238 priv_identity_key=c_identity_keys.priv, 239 identity_key=c_identity_keys.pub, 240 priv_handshake_key=c_handshake_keys.priv, 241 other_identity_key=b_identity_keys.pub, 242 other_handshake_key=b_handshake_keys.pub, 243 priv_ratchet_key=c_ratchet_keys.priv, 244 ratchet_key=c_ratchet_keys.pub, 245 other_ratchet_key=b_ratchet_keys.pub) 246 247 return Conversations(ab, ac, ba, bc, ca, cb) 248 249 250def create_conversations( 251 axolotl_a, a_identity_keys, a_handshake_keys, a_ratchet_keys, 252 axolotl_b, b_identity_keys, b_handshake_keys, b_ratchet_keys, 253 axolotl_c, c_identity_keys, c_handshake_keys, c_ratchet_keys, 254 mkey_ab, mkey_ac, mkey_bc): 255 ab = axolotl_a.create_conversation( 256 other_name=axolotl_b.name, 257 mkey=mkey_ab, 258 mode=True, 259 priv_identity_key=a_identity_keys.priv, 260 identity_key=a_identity_keys.pub, 261 other_identity_key=b_identity_keys.pub, 262 other_ratchet_key=b_ratchet_keys.pub) 263 264 ac = axolotl_a.create_conversation( 265 other_name=axolotl_c.name, 266 mkey=mkey_ac, 267 mode=False, 268 priv_identity_key=a_identity_keys.priv, 269 identity_key=a_identity_keys.pub, 270 other_identity_key=c_identity_keys.pub, 271 priv_ratchet_key=a_ratchet_keys.priv, 272 ratchet_key=a_ratchet_keys.pub) 273 274 ba = axolotl_b.create_conversation( 275 other_name=axolotl_a.name, 276 mkey=mkey_ab, 277 mode=False, 278 priv_identity_key=b_identity_keys.priv, 279 identity_key=b_identity_keys.pub, 280 other_identity_key=a_identity_keys.pub, 281 priv_ratchet_key=b_ratchet_keys.priv, 282 ratchet_key=b_ratchet_keys.pub) 283 284 bc = axolotl_b.create_conversation( 285 other_name=axolotl_c.name, 286 mkey=mkey_bc, 287 mode=True, 288 priv_identity_key=b_identity_keys.priv, 289 identity_key=b_identity_keys.pub, 290 other_identity_key=c_identity_keys.pub, 291 other_ratchet_key=c_ratchet_keys.pub) 292 293 ca = axolotl_c.create_conversation( 294 other_name=axolotl_a.name, 295 mkey=mkey_ac, 296 mode=True, 297 priv_identity_key=c_identity_keys.priv, 298 identity_key=c_identity_keys.pub, 299 other_identity_key=a_identity_keys.pub, 300 other_ratchet_key=a_ratchet_keys.pub) 301 302 cb = axolotl_c.create_conversation( 303 other_name=axolotl_b.name, 304 mkey=mkey_bc, 305 mode=False, 306 priv_identity_key=c_identity_keys.priv, 307 identity_key=c_identity_keys.pub, 308 other_identity_key=b_identity_keys.pub, 309 priv_ratchet_key=c_ratchet_keys.priv, 310 ratchet_key=c_ratchet_keys.pub) 311 312 return Conversations(ab, ac, ba, bc, ca, cb) 313 314 315def run_threaded_exchanges(exchange, conversations): 316 event = Event() 317 318 queue_ab = Queue() 319 exchange_ab = ThreadedExchange(exchange, 320 conversations.ab, conversations.ba, 321 event, queue_ab) 322 323 queue_ac = Queue() 324 exchange_ac = ThreadedExchange(exchange, 325 conversations.ac, conversations.ca, 326 event, queue_ac) 327 328 queue_bc = Queue() 329 exchange_bc = ThreadedExchange(exchange, 330 conversations.bc, conversations.cb, 331 event, queue_bc) 332 333 exchange_ab.start() 334 exchange_ac.start() 335 exchange_bc.start() 336 337 event.set() 338 339 assert queue_ab.get() and queue_ac.get() and queue_bc.get() 340