20
Test your code in real environment

Mobile Weekend Budapest presentation

Embed Size (px)

Citation preview

Page 1: Mobile Weekend Budapest presentation

Test your code in real environment

Page 2: Mobile Weekend Budapest presentation

Short introduc,on

Peter Adam WiesnerSo0ware Engineer @ Skyscanner

iOS run(me, code architecturescyberpunk

Twi$er - @peteee24E-mail - [email protected] - @wiesnerpe<

Page 3: Mobile Weekend Budapest presentation

What is the dream of every developer?

Development of apps, that the users love and find them useful :)

What is the coders worst nightmare?

Page 4: Mobile Weekend Budapest presentation

Human nature

One key characteris.c of the human evolu.on is , that we try to create tools for the problems we already solved. This helps us

crea.ng more complex systems

Same for apps. More and more classes are working together to achieve a goal

.. and we trust every class will do its job correctly

Page 5: Mobile Weekend Budapest presentation

Try to handle the situa0onUnit tests << Integra-on tests << System tests << ?

⬆ tes%ng level == ⬆ number of dependency, that need to be covered

we should simulate real environments

can't write unit test for every inout-output configura5on, hope we covered the edge cases

Page 6: Mobile Weekend Budapest presentation

Best defence is a,ackNot new idea(Ne,lix)

How to apply this to mobile apps?

Change some dependencies' behaviour, try to keep the system in unstable state

Page 7: Mobile Weekend Budapest presentation

Theory

Need a tool that can replace arbitary method of arbitary class to behave in an arbitary different way

Page 8: Mobile Weekend Budapest presentation

Dixie history

1. Unit tests were strangely succeeding ➡ Chaos Monkey

2. Collec9ng ideas ➡ make a library

3. Research lab ➡ Beta

4. Open source

Page 9: Mobile Weekend Budapest presentation

Result

[Dixie new] .Profile([DixieProfileEntry entry:[MyClass class] selector:@selector(doStuff:) chaosProvider:[DixieNilChaosProvider new]]) .Apply();

Page 10: Mobile Weekend Budapest presentation

How does ObjC work?

1. [self doStuff:@2];

2. (id(*)(id, SEL, id))objc_msgSend(self,@selector(doStuff:), @2);

3. Looking up in the methods of the class and superclass

4. if found ➡ jump to the registered IMP func>on-pointer

Page 11: Mobile Weekend Budapest presentation

Swizzling

"replacing regitered IMP func3on-pointers with the help of Objec3ve-C run3me C func3ons"

— NSHipster

• class_addMethod

• class_replaceMethod

• imp_implementationWithBlock

• We need to know the signature of the target method, when wri5ng the code

Page 12: Mobile Weekend Budapest presentation

Prepare for the unknown• Need a general block, that can be used to swizzle arbitrary

method

• Long list of return and param types: BOOL, short, double, id, selector, block...

• Idea:

• use variadic parameters

• parse them so they will be objects

• copy the code for every type by defining macros

Page 13: Mobile Weekend Budapest presentation

Something like this

imp_implementationWithBlock([type]^(id victim, ...){ //Create call environment

//Parse parameters

//Call chaos provider block block(victim, environment)

//Decide what to return return ([type]*)environment.returnValue })

Page 14: Mobile Weekend Budapest presentation

Using the unknownSome%mes we need to call an unknown func%on (previous problem

from the side of the caller)

if (numOfParams == 1) f(obj1);else if (numOfParams == 2) f(obj1, obj2)else ...

➡ Not scalable :(

Page 15: Mobile Weekend Budapest presentation

Using the unknownMacro magic

#define o(object) /type(object) == @encode(int) ? (int)object : /type(object) == @encode(double) ? (double)object : /...

➡ ?: does not support different return types (C++ macros are working in compile 8me)

Page 16: Mobile Weekend Budapest presentation

Using the unknownFFI(Foreign Func-on interface)

ffi_cif cif; //call objectffi_type *args[1]; //arg typesvoid *values[1]; //arg valuesffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args)ffi_call(&cif, IMP, &returnValue, values);

➡ 10% unknown crashes for class methods + dependency

Page 17: Mobile Weekend Budapest presentation

Using the unknownNSInvoca)on - FFI by Apple

invokeUsingIMP - private method, that does not use objc_msgSend

NSMethodSignature* signature = ...;NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];

//set args

[invocation invokeUsingIMP:implementation];

//get return value

Page 18: Mobile Weekend Budapest presentation

Toolbox of opportuni.es

This is only the first step, how to advance? ➡ Combine behaviours -> Nil, Block, Composit, ExcepAon ➡ Invent new tools -> AST parsing, dependency recogniAon

Page 19: Mobile Weekend Budapest presentation

To takeaway

1. Hope for the best, expect the worst, beside wri4ng unit tests, challenge the applica4on with different inputs, in real life environment

2. To simulate strange scenarios, Dixie is a good tool:h@ps://github.com/Skyscanner/Dixie

Page 20: Mobile Weekend Budapest presentation

Ques%ons?

Twi$er - @peteee24E-mail - [email protected] - @wiesnerpe<

Skyscanner Budapest - h2ps://www.facebook.com/hashtag/skyscannerbpSkyscanner - h2p://www.skyscanner.net/jobs/