• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
12 Hours To Rate A Rails Application
 

12 Hours To Rate A Rails Application

on

  • 4,496 views

In some situations, it's useful to be able to evaluate a Rails application quickly....

In some situations, it's useful to be able to evaluate a Rails application quickly.
I talk about how I work to get the most data as possible to get a good picture of whether an application is well-maintained, and will be easy to maintain later.

Statistics

Views

Total Views
4,496
Views on SlideShare
4,436
Embed Views
60

Actions

Likes
6
Downloads
34
Comments
0

2 Embeds 60

http://www.slideshare.net 41
http://speakerrate.com 19

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • <br />
  • a big company wants to acquire a startup that has a rails application. <br /> before the sale goes through, they want to be sure they get value for money. <br /> they call in an expert to have a look. <br /> you are the expert. <br />
  • <br />
  • You go to the startup, you sign an NDA, and you get access to the code. <br /> You usually have full cooperation of the team, who would be eager for you to give a good report. <br />
  • sit down with the team <br /> they will make an introduction <br /> and you can observe them: <br /> looking at people you can already form an idea <br />
  • you have experience which will allow you to tell whether you have a team that will produce good to great software. <br />
  • One guy: usually bad sign - easier to slack off when you&#x2019;re alone <br /> commit everything <br /> maintainable test <br /> broken windows <br /> automation: manual scripts/hacks a person is not even consciously aware of <br /> simple peer pressure in everything <br />
  • I&#x2019;m sure there are many learned articles about group dynamics, about personality types in a team, etc ... <br /> the innovator: keeps up with what&#x2019;s out there, wants to be on top of the next great thing <br /> the automator: more a sysadmin profile maybe - someone who likes scripting and making everything run smoothly <br /> the ant: obsessive-compulsive types who want to have every detail perfect. <br />
  • You&#x2019;ll notice I don&#x2019;t include him ... <br /> <br /> Bottom line, after you&#x2019;ve worked a while, you get a feel for what constitutes a good team. Getting to know a team can already tell you something about the application you&#x2019;re about to look at ... <br /> <br /> On a less pleasant note, some of those people will be employed by the buyer. key players in the team <br />
  • <br />
  • <br />
  • tools I think you cannot do without. Even if the bug tracker is a text file. <br />
  • <br />
  • so you sat down with the team, you discussed the application, their philosophy, the deployment, other aspects ... <br /> <br />
  • it&#x2019;s time to dive in, and see what we have here. <br />
  • does it work ? <br /> does the application match the vision ? <br /> Is it clear at all ? &#x2018;don&#x2019;t make me think&#x2019; <br /> do you manage to get pesky 500s and 404 ? <br />
  • that shouldn&#x2019;t take too long. <br />
  • then you can start inventorizing what you&#x2019;ve got. <br /> First off, what version of rails are they using ? <br /> I think it&#x2019;s a good sign when it&#x2019;s a reasonably recent version. <br />
  • Same for plugins. <br /> what gems, what plugins are they using ? <br /> Is it the last version ? <br />
  • I&#x2019;m a firm believer in the natural selection of open source <br /> Are they popular ? <br /> Are they maintained ? <br />
  • are the plugins and gems easily updatable ? <br />
  • another aspect you might not think of, but will interest the acquirer: what license is the code under ? <br /> Obviously, for commercial code, the freer the better - MIT or BSD license over GPL <br />
  • I think I look out for, is the Not Invented Here syndrom. <br /> some people will not trust plugins they have not written themselves. <br /> That&#x2019;s fine, but <br /> - reinventing the wheel <br /> - maintaining the wheel <br /> - by releasing it, you express your confidence that it is good code. <br /> - adoption and maintenance by others <br /> <br />
  • OK, plugins and gems are inventorized. <br />
  • you often have a sizeable code base to look at ... where to start ? <br /> <br /> Where would you start ? <br />
  • what&#x2019;s the action in the application ? <br />
  • <br />
  • clearly named ? <br /> may not be clear to you - domain-dependent <br /> ideally googleable <br /> sometimes internal jargon for the firm <br /> ask someone in the same business what a term means <br /> ask a developer what it means <br />
  • we now have a very high level view of the application. <br /> <br /> Now, before continuing, there is one priority <br />
  • <br />
  • One way to start analyzing a large amount of code, is by using metrics. <br />
  • I&#x2019;m going to go a little bit more in-depth about the metric tools. <br /> There have been many presentations and blog posts about the subject, I&#x2019;m going to try to go a little bit further, to give you an idea of what&#x2019;s under the hood <br />
  • the first code metric in history are lines of code. <br /> Unfortunately, they don&#x2019;t tell you very much: imagine you add a few lines of comment, you break up an expression into several lines - for the same code you can double the number of lines. <br /> They give you an idea of the approximate size. <br />
  • <br />
  • Most of the metrics tool rest on ruby parsing. <br /> RubyParser and ParseTree are both tools developed by Kevin Clarke and Ryan Biggs <br /> Also known as the Ruby Sadists <br /> <br /> The idea is to navigate the abstract syntax tree = <br /> code represented as a tree <br /> symbolic expressions are a good way to represent this tree <br /> list-based data structures that represent semi-structured data. <br /> . Lisp, Scheme <br /> the output of ruby parser and parsetree is a symbolic expression. <br />
  • Flog is one of the tools made by Rian Bigg <br /> It gives a measure of code complexity. <br /> <br /> For every tool I try to give first a description, <br /> then some implementation details <br /> and finally what is expected for good code <br />
  • How flog works: <br /> the AST is recursively accessed, and a calculation is made <br /> the calculation happens with ABC <br /> Assignment Branch Conditions - a traditional measure of code complexity. <br />
  • The result is a series of number - per class and per method. <br />
  • Per method, you expect something like this <br />
  • <br />
  • <br />
  • <br />
  • guess where the name &#x2018;saikuro&#x2019; comes from <br /> Japanese people have this habit of taking over words that indicate new concepts <br /> bi-ru co-hee <br /> it&#x2019;s cyclo as used by japanese people <br /> number of linearly independent paths through a program&apos;s source code. <br /> it&#x2019;s also a measure of code complexity <br />
  • lexer: step before parsing - <br /> split program = characters - into tokens <br />
  • <br />
  • <br />
  • we come to the less quantitative tools - roodi and reek find design issues for you. <br />
  • abc metric like flog <br /> assignment in conditional <br /> missing else in a case <br /> class variables <br /> <br /> <br /> <br />
  • <br />
  • Control couple: the execution of a method depends on one of the parameters (conditional on parameter). Also when one of parameters is defaulted to true or false <br /> Data clump: variables appearing together all the time - suggesting missing abstraction <br /> feature envy: when code fragment references other object more than it references itself, or when several objects do the same kind of manipulation on a particular kind of object <br /> Simulated polymorphism: case statements, several ifs, is_a_kind_of? <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • The tool we all know to check our test coverage <br />
  • <br />
  • <br />
  • Now, code coverage doesn&#x2019;t say much. <br /> For a good test set, you need 100%, but that&#x2019;s a minimum requirement. <br /> You can have 100% coverage without <br />
  • Heckle is really interesting in theory, difficult to apply in practice. <br />
  • <br />
  • in the next mutation, it changed this to nil <br /> the one after that, ti change the symbol to something else <br /> <br />
  • <br />
  • <br />
  • So I looked at the metrics, and I read some of the code that was flagged. time flies, and we have only 7 hours to go <br />
  • and it&#x2019;s time for lunch <br />
  • <br />
  • revigorated, it&#x2019;s time to continue <br /> <br /> with metrics, you got to see their worst. the monster methods, the antipatterns ... <br /> now you could also apply some normal codereading <br /> ask them what the core is, what their best code is <br />
  • code should be readable. Ideally like a book <br /> <br /> At the very least it shouldn&#x2019;t take too much effort to understand what&#x2019;s going on. <br />
  • rails is not slow, developers make bad use of the data base <br /> it&#x2019;s not because we use an ORM that we can drop all knowledge <br />
  • this is a plugin I&#x2019;d rather not see. It means that you can go several levels of has_many_through <br /> in this case, it might be a good idea to reconsider. either using sql, or views at db level, or denormalize <br />
  • We&#x2019;ve looked at models, views <br /> in fact maybe we need a metric tool for views, too <br /> <br /> divitis <br /> javascript in the body <br /> unindented <br /> too much logic in view <br />
  • <br />
  • it&#x2019;s time to have a closer look at the tests. <br /> first off, it makes sense to run them <br />
  • <br />
  • automated test suites fail when they expect not to have any maintenance <br /> tests take maintenance <br /> tests are software <br /> changes will occur, and they can be of 2 natures <br />
  • does that remind you of something ? <br />
  • <br />
  • deployment is important, but not that critical <br /> if you&#x2019;ve got a well-structured, well-written, modular application, you can change deployment fairly easily <br />
  • one thing to add in your description of the application: a schematic of the deployment <br /> they should be able to provide that, if only on a paper napkin <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • those were for me the important points <br /> if what we saw up to now is ok, they will get a good report. <br /> the following slides will get them a glowing report, with exclamation points <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • It&#x2019;s time to go home with your notes and write a report <br /> <br /> Are there any questions ? <br />
  • I hope you enjoyed the talk, and that you got something out of it. <br /> <br />

12 Hours To Rate A Rails Application 12 Hours To Rate A Rails Application Presentation Transcript

  • hours to rate a Rails application Elise Huard @elise_huard http://jabberwocky.eu Wednesday 31 March 2010
  • Acquisition Wednesday 31 March 2010
  • Maintenance Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 12:00 Wednesday 31 March 2010
  • Team Wednesday 31 March 2010
  • Team: use your gut Wednesday 31 March 2010
  • One man’s application Wednesday 31 March 2010
  • innovator automator Control Freak Wednesday 31 March 2010
  • ... Wednesday 31 March 2010
  • Vision Wednesday 31 March 2010
  • Methodology Wednesday 31 March 2010
  • Bug Tracker Version control Wednesday 31 March 2010
  • Back seat driver Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 10:00 Wednesday 31 March 2010
  • Try the app Wednesday 31 March 2010
  • does it work ? Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 09:45 Wednesday 31 March 2010
  • Rails version Wednesday 31 March 2010
  • plugins and gems Wednesday 31 March 2010
  • Wednesday 31 March 2010
  • managing updates piston git submodules (svn externals) Wednesday 31 March 2010
  • Licenses Wednesday 31 March 2010
  • NIH syndrom Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 09:00 Wednesday 31 March 2010
  • All that code Wednesday 31 March 2010
  • config/routes.rb map.root :controller => 'root', :action => 'index' map.namespace :admin do |admin| admin.resources :grids do |grid| grid.resources :nodes grid.resources :edges, :collection => {:all => :post, :update_all => :post} grid.resources :walkers end end map.resources :nodes, :only => [:new,:create,:show,:destroy], :collection => {:directions => :put} map.resources :walkers, :only => [:show,:new,:create,:destroy], :collection => {:select => :get} map.resources :itineraries, :only => [:show] map.four_oh_four '*path' , :controller => 'four_oh_fours' Wednesday 31 March 2010
  • models railroad -M | dot Tpng > models.png rubymine ctrl-alt-D uml dumper (needs maintenance) Wednesday 31 March 2010
  • names “There are only two hard things in Computer Science: cache invalidation and naming things” Phil Karlton Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 08:30 Wednesday 31 March 2010
  • Coffee Wednesday 31 March 2010
  • metrics Wednesday 31 March 2010
  • Know thine tools Wednesday 31 March 2010
  • LOC rake stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 2702 | 2150 | 36 | 158 | 4 | 11 | | Helpers | 358 | 303 | 0 | 22 | 0 | 11 | | Models | 1358 | 1104 | 30 | 117 | 3 | 7 | | Libraries | 2286 | 1655 | 38 | 152 | 4 | 8 | | Integration tests | 0 | 0 | 0 | 0 | 0 | 0 | | Functional tests | 1687 | 1322 | 31 | 195 | 6 | 4 | | Unit tests | 1356 | 1079 | 27 | 158 | 5 | 4 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | 9747 | 7613 | 162 | 802 | 4 | 7 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 5212 Test LOC: 2401 Code to Test Ratio: 1:0.5 Wednesday 31 March 2010
  • RubyParser and Parsetree Ryan Davis and Eric Hodel (‘Ruby Sadists’) Wednesday 31 March 2010
  • RubyParser and Parsetree Abstract syntax tree RubyParser.new.parse(File.read(‘metrics.rb’),‘metric.rb’) class Metrics s(:class,:Metrics, nil, def probe s(:scope, s(:defn,:probe, puts "good" s(:args), end s(:scope, end s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "good")))))))) Symbolic Expression (Sexp) Ruby2Ruby Wednesday 31 March 2010
  • flog ‘the pain your code is in’ Wednesday 31 March 2010
  • FLOG Weighing the AST with factors Assignment Branch Condition (ABC) def process_if(exp) add_to_score :branch process exp.shift # cond penalize_by 0.1 do process exp.shift # true process exp.shift # false end s() end Wednesday 31 March 2010
  • FLOG flog lib/flog.rb 647.8: flog total 13.8: flog/method average 87.5: Flog#output_details 58.8: Flog#process_iter 54.2: Flog#flog 48.8: Flog#parse_options 34.1: Flog#none 23.2: Flog#output_method_details 22.1: Flog#score_method 16.0: Flog#process_block_pass 15.6: Flog#report 15.2: Flog#expand_dirs_to_files 15.0: Flog#klass_name Wednesday 31 March 2010
  • FLOG Very good: < 20 All Right: < 50 Wednesday 31 March 2010
  • FLAY code similarities Wednesday 31 March 2010
  • FLAY RubyParser def mass @mass ||= self.structure.flatten.size end Hash of structure of nodes with mass > threshold self.hashes[node.structural_hash] << node analyze: if same hash = similar if same node = identical Wednesday 31 March 2010
  • FLAY flay *.rb Total score (lower is better) = 621 1) IDENTICAL code found in :defn (mass*2 = 188) channel.rb:48 clip.rb:80 2) Similar code found in :defn (mass = 93) channel.rb:150 clip.rb:110 clip.rb:116 3) Similar code found in :defs (mass = 58) contact.rb:32 contact.rb:37 Wednesday 31 March 2010
  • Saikuro cyclomatic complexity Wednesday 31 March 2010
  • Saikuro ruby-lex every keyword is interpreted into ‘state’ state used to calculate if, unless, while, until, for, elsif, when, rescue (blocks) Recursively Wednesday 31 March 2010
  • Saikuro Wednesday 31 March 2010
  • Saikuro Good: methods < 5 Wednesday 31 March 2010
  • Roodi Ruby Object Oriented Design Inferometer (what ?) “design issues” Wednesday 31 March 2010
  • Roodi RubyParser visitor pattern visitor: checker (Configurable) visitable: parsed nodes = extensible Wednesday 31 March 2010
  • Roodi app/controllers/itineraries_controller.rb:4 - Method name "show" cyclomatic complexity is 14. It should be 8 or less. app/models/itinerary.rb:41 - Block cyclomatic complexity is 6. It should be 4 or less. app/controllers/itineraries_controller.rb:4 - Method "show" has 30 lines. It should have 20 or less. app/helpers/application_helper.rb:27 - Method "clippy" has 26 lines. It should have 20 or less. Wednesday 31 March 2010
  • Reek Control Couple Data Clump Feature Envy Large Class Long Method Long Parameter List Simulated Polymorphism Uncommunicative Name Wednesday 31 March 2010
  • Reek RubyParser extends parsed nodes traverses nodes returns code after Ruby2Ruby Wednesday 31 March 2010
  • Reek UserSessionsController has no descriptive comment (Irresponsible Module) UserSessionsController#destroy calls current_user_session twice (Duplication) app/controllers/users_controller.rb -- 5 warnings: UsersController has no descriptive comment (Irresponsible Module) UsersController tests @aid_app at least 4 times (Simulated Polymorphism) UsersController#create calls params 3 times (Duplication) UsersController#create calls params[:user] 3 times (Duplication) ... Wednesday 31 March 2010
  • Churn Frequent changes may indicate issue Wednesday 31 March 2010
  • Churn Not only classes but also methods (RubyParser) Version control: git, Hg, svn Locates changes in source using logs (as in git log) Wednesday 31 March 2010
  • Churn +-------------------------------------------------+---------------+ | file_path | times_changed | +-------------------------------------------------+---------------+ | db/schema.rb | 26 | | config/routes.rb | 24 | | app/controllers/application_controller.rb | 22 | | app/controllers/add_apps_controller.rb | 22 | | config/environment.rb | 20 | | app/views/layouts/application.html.erb | 20 | | app/models/ability.rb | 18 | ... Wednesday 31 March 2010
  • Churn common sense ... mostly useful in maintenance phase Wednesday 31 March 2010
  • Rcov Wednesday 31 March 2010
  • Rcov Executes test keeps track of the executed lines Using C extension when possible to hook into MRI (experimental for 1.9) Wednesday 31 March 2010
  • Rcov Total coverage: comments included Wednesday 31 March 2010
  • Rcov good: 100% coverage Wednesday 31 March 2010
  • Heckle Wednesday 31 March 2010
  • Heckle ParseTree + Ruby2Ruby mutate doesn’t work for ruby 1.9 (ParseTree) time-consuming: combinatorials more for small programs (gems, scripts) Wednesday 31 March 2010
  • Heckle Initial tests pass. Let's rumble. ********************************************************************** *** AidApp#property_names loaded with 4 possible mutations ********************************************************************** 4 mutations remaining... Replacing AidApp#property_names with: --- original +++ mutation def property_names - (meta_policy and meta_policy.property_names_for(:aid_app)) + (nil and meta_policy.property_names_for(:aid_app)) end Wednesday 31 March 2010
  • rake stats size Flog Flay code complexity code similarities Roodi Saikuro Reek cyclomatic antipatterns complexity Heckle Rcov test coverage Wednesday 31 March 2010
  • metric_fu Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 06:30 Wednesday 31 March 2010
  • Lunch Wednesday 31 March 2010
  • and more Coffee Wednesday 31 March 2010
  • read some code Wednesday 31 March 2010
  • Expressive code Wednesday 31 March 2010
  • Database db/schema.rb seed data everything in migrations ? Wednesday 31 March 2010
  • Nested_has_many_through Wednesday 31 March 2010
  • views Bad: unindented divitis javascript in the body too much logic in viewiew Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 04:30 Wednesday 31 March 2010
  • run tests Wednesday 31 March 2010
  • Time for tests (or autotest/ci) Wednesday 31 March 2010
  • maintainable test suite tests = software changes in implementation changes in requirements Wednesday 31 March 2010
  • maintainable test suite express code responsibility hide incident detail DRY Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 02:30 Wednesday 31 March 2010
  • Deployment Wednesday 31 March 2010
  • Deployment Wednesday 31 March 2010
  • Deployment Automation, automation, automation Wednesday 31 March 2010
  • Deployment deployment = software same rules apply Wednesday 31 March 2010
  • Traffic Wednesday 31 March 2010
  • Performance tests Bottlenecks Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 01:00 Wednesday 31 March 2010
  • Brownie Points Wednesday 31 March 2010
  • Continuous integration ... and they’re using it Wednesday 31 March 2010
  • Documentation of any kind ... and it’s up to date Wednesday 31 March 2010
  • monitoring exception notification Log analyzers Wednesday 31 March 2010
  • testing javascripts Continuous performance testing Wednesday 31 March 2010
  • 12 hours To Rate a Rails Application 00:00 Wednesday 31 March 2010
  • http://railroad.rubyforge.org/ http://www.igvita.com/2008/12/11/ruby-ast-for-fun-and-profit/ http://ruby.sadi.st/Ruby_Sadist.html http://goruco2008.confreaks.com/04_davis.html http://cwd.dhemery.com/2009/11/wmaat/ http://c2.com/cgi/wiki?AbcMetric http://hissa.nist.gov/HHRFdata/Artifacts/ITLdoc/235/title.htm http://blog.rubybestpractices.com/posts/judofyr/sexp-for- rubyists.html Elise Huard @elise_huard elise@elisehuard.be http://jabberwocky.eu Wednesday 31 March 2010