• Shutting down the Devver Test Accelerator

    by Ben

    After much deliberation, we've decided to shut down our Test Accelerator product on January 22nd, 2010. (the Accelerator was previously just known as "Devver", but to clarify between our old product and Caliper, we're referring to it as the "Accelerator" or the "Test Accelerator").

    This has been a difficult decision for us. Understandably, some people have been confused and disappointed by this news, so I wanted to take some time to explain our decision.

    For over a year, we worked to build our vision of accelerated Ruby testing in the cloud. We made our share of mistakes and learned a lot in the process. Ultimately, we found the demand was too small to warrant overcoming all the technical challenges that were harder than we anticipated.

    We had many different technical challenges, but it boils down to this: we underestimated the difficulty of making it simple to run Ruby/Rails tests in the cloud.

    When we began working on the Accelerator, we knew we would need many features: automatic installation of gems, automatic setup of common databases, and support for Test:Unit, Shoulda, and RSpec. However, other features caught us by surprise. For instance, many projects required running daemons, such as memcached or Solr to be running when the tests executed. Also, it was common for projects to work fine on a user's machine, but fail in the cloud due to undeclared RubyGem dependencies (or dependencies that lacked sufficient version information). Some problems were extra difficult because, due to costs, we needed to be able to run many projects on a single EC2 instance (and it's currently not possible to create virtual machines within EC2 Xen instances).

    We worked hard to overcome these challenges, but it was still too common for users to discover that running tests in the cloud required additional work on their part (or, in some cases, that their project was not supported). And even worse, users had to jump through these hoops before they could assess whether or not the Accelerator would speed up their tests enough to make the process worth it. Because the potential benefit and possible configuration time were both unknown, many users understandably gave up before they experienced the time savings of running tests in parallel. And unfortunately, the projects that were most likely to need acceleration (those with large test suites), were also the most likely to have complex dependencies and require the most setup work.

    While we may have been able to solve these problems with a lot of additional engineering, we also found that only a small percentage of teams really needed test acceleration. Some teams loved our solution, because they had test suites that took 10, 20, or even 45 minutes to run. However, most projects had smaller test suites. We found that many teams didn't mind waiting for suites that took 3-5 minutes (or, more accurately, didn't mind enough to justify the considerable time investment of setting up tests on the Accelerator).

    So, after much discussion, we decided that we needed to create a product that would help a larger set of Ruby teams and require significantly less setup to provide value. Those discussions led to Caliper, a tool to identify risky code and technical debt in Ruby code.

    Focus is key in a startup, especially a small one like ours. While we considered keeping the Accelerator running in maintenance mode, we realized we could not provide the level of support our users deserve while executing effectively on Caliper. As a result, we've decided to shut down the Accelerator indefinitely.

    We deeply appreciate each and every person who helped us with the Accelerator, either by using it, or giving us ideas, feedback, and encouragement. We could not have gotten as far as we did without the help from users, friends, and mentors.

    It pains us to shut down the service and we apologize for any inconvenience this causes our users. We hope that you understand our decision and we look forward to helping you improve your code with Caliper.

    (Accelerator users: if you need to speed up your tests, here are some possible alternatives to Devver: multitest, parallel_specs, Testjour, and DeepTest. I don't have experience with these tools, so I can't comment on how well they work myself, but you may want to check them out.)

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on January 6th, 2010 by Ben in Devver and tagged , , , .

  • Caliper: Next Steps

    by Ben

    We released the first version of Caliper just under two months ago. Since then, we've fixed bugs, made improvements, and rolled out new features. The feedback we've gotten from the community has been encouraging and your suggestions have helped up improve Caliper each week.

    Initially, we simply wanted to take an existing tool (namely, metric_fu) and make it dead simple to set up, so that all open-source projects could get access to metric data. However, our larger goal is to improve the usability, features, and data presentation in Caliper so it becomes an indispensable part of your regular Ruby development process.

    To that end, I'm happy to announce that support for private projects is on the road map. We're still working out the details, but we plan to release this feature within the next thirty days.

    At the same time, we'll work with users to figure out how we can make metrics useful enough to be a regular part of your process (by "regular", we mean that we hope you use metrics at least once a week).

    We recently put out a short survey (results here) to try to assess what features are most important for our users. By looking at the results (somewhat limited, likely due to overly wordy questions on my part) and based on some conversations I had at RubyConf, we see a few possible scenarios for where to take Caliper next.

    "Code exploration"
    In this scenario, you'd primarily use Caliper to jump into an existing code base, in order to help you better understand where the problematic areas are. This might be used by consultants for a project-level code review, for understanding how to start contributing to an open-source project, or even to periodically do a survey of problems of your own project. The primary features for this scenario would be our Hot Spots feature (which list the worst methods, classes, and files in the project). Important new features include a display that shows the source code with the problems displayed alongside the source.

    "Quality monitoring"
    In this scenario, the primary usage for Caliper is to set and maintain certain metrics thresholds within your code base. You'd set levels for the various tools and then get alerts when those thresholds are reached. Key features would include an ability to customize thresholds for each tool, a dashboard that displays offending classes and methods, and customizable notifications.

    "Refactoring assistant"
    In this scenario, a single developer uses Caliper to assist them in refactoring up his/her code, perhaps after reviewing a commit that will be pushed, or because a specific section of code is known to be overly complex. Caliper would both find the biggest problems and provide feedback on how refactorings change the metrics. Key features would include an improved commit-based view of metric changes as well as the ability to push code directly to Caliper before merge that code into a shared 'master' branch.

    Do any of these scenarios resonate with you? Would you prefer one over another? Is there another scenario that would be more useful? If you are currently using metrics in your project, how do you use them and what features do you want? If you don't currently use metrics, what features would make you change your mind? Please make your voice heard in the comments, so we can make Caliper a valuable addition to your toolbox.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on November 24th, 2009 by Ben in Devver and tagged , , .

  • Improving Code using Metric_fu

    by Dan

    Often, when people see code metrics they think, "that is interesting, I don't know what to do with it." I think metrics are great, but when you can really use them to improve your project's code, that makes them even more valuable. metric_fu provides a bunch of great metric information, which can be very useful. But if you don't know what parts of it are actionable it's merely interesting instead of useful.

    One thing when looking at code metrics to keep in mind is that a single metric may not be as interesting. If you look at a metric trends over time it might help give you more meaningful information. Showing this trending information is one of our goals with Caliper. Metrics can be your friend watching over the project and like having a second set of eyes on how the code is progressing, alerting you to problem areas before they get out of control. Working with code over time, it can be hard to keep everything in your head (I know I can't). As the size of the code base increases it can be difficult to keep track of all the places where duplication or complexity is building up in the code. Addressing the problem areas as they are revealed by code metrics can keep them from getting out of hand, making future additions to the code easier.

    I want to show how metrics can drive changes and improve the code base by working on a real project. I figured there was no better place to look than pointing metric_fu at our own devver.net website source and fixing up some of the most notable problem areas. We have had our backend code under metric_fu for awhile, but hadn't been following the metrics on our Merb code. This, along with some spiked features that ended up turning into Caliper, led to some areas getting a little out of control.

    Flay Score before cleanup

    When going through metric_fu the first thing I wanted to start to work on was making the code a bit more DRY. The team and I were starting to notice a bit more duplication in the code than we liked. I brought up the Flay results for code duplication and found that four databases models shared some of the same methods.

    Flay highlighted the duplication. Since we are planning on making some changes to how we handle timestamps soon, it seemed like a good place to start cleaning up. Below are the methods that existed in all four models. A third method 'update_time' existed in two of the four models.

     def self.pad_num(number, max_digits = 15)
        "%%0%di" % max_digits % number.to_i
      end
    
      def get_time
          Time.at(self.time.to_i)
      end
    

    Nearly all of our DB tables store time in a way that can be sorted with SimpleDB queries. We wanted to change our time to be stored as UTC in the ISO 8601 format. Before changing to the ISO format, it was easy to pull these methods into a helper module and include it in all the database models.

    module TimeHelper
    
      module ClassMethods
        def pad_num(number, max_digits = 15)
          "%%0%di" % max_digits % number.to_i
        end
      end
    
      def get_time
          Time.at(self.time.to_i)
      end
    
      def update_time
        self.time = self.class.pad_num(Time.now.to_i)
      end
    
    end
    

    Besides reducing the duplication across the DB models, it also made it much easier to include another time method update_time, which was in two of the DB models. This consolidated all the DB time logic into one file, so changing the time format to UTC ISO 8601 will be a snap. While this is a trivial example of a obvious refactoring it is easy to see how helper methods can often end up duplicated across classes. Flay can come in really handy at pointing out duplication that over time that can occur.

    Flog gives a score showing how complex the measured code is. The higher the score the greater the complexity. The more complex code is the harder it is to read and it likely contains higher defect density. After removing some duplication from the DB models I found our worst database model based on Flog scores was our MetricsData model. It included an incredibly bad high flog score of 149 for a single method.

    File Total score Methods Average score Highest score
    /lib/sdb/metrics_data.rb 327 12 27 149

    The method in question was extract_data_from_yaml, and after a little refactoring it was easy to make extract_data_from_yaml drop from a score of 149 to a series of smaller methods with the largest score being extract_flog_data! (33.6). The method was doing too much work and was frequently being changed. The method was extracting the data from 6 different metric tools and creating summary of the data.

    The method went from a sprawling 42 lines of code to a cleaner and smaller method of 10 lines and a collection of helper methods that look something like the below code:

      def self.extract_data_from_yaml(yml_metrics_data)
        metrics_data = Hash.new {|hash, key| hash[key] = {}}
        extract_flog_data!(metrics_data, yml_metrics_data)
        extract_flay_data!(metrics_data, yml_metrics_data)
        extract_reek_data!(metrics_data, yml_metrics_data)
        extract_roodi_data!(metrics_data, yml_metrics_data)
        extract_saikuro_data!(metrics_data, yml_metrics_data)
        extract_churn_data!(metrics_data, yml_metrics_data)
        metrics_data
      end
    
      def self.extract_flog_data!(metrics_data, yml_metrics_data)
        metrics_data[:flog][:description] = 'measures code complexity'
        metrics_data[:flog]["average method score"] = Devver::Maybe(yml_metrics_data)[:flog][:average].value(N_A)
        metrics_data[:flog]["total score"]   = Devver::Maybe(yml_metrics_data)[:flog][:total].value(N_A)
        metrics_data[:flog]["worst file"] = Devver::Maybe(yml_metrics_data)[:flog][:pages].first[:path].fmap {|x| Pathname.new(x)}.value(N_A)
      end
    

    Churn gives you an idea of files that might be in need of a refactoring. Often if a file is changing a lot it means that the code is doing too much, and would be more stable and reliable if broken up into smaller components. Looking through our churn results, it looks like we might need another layout to accommodate some of the different styles on the site. Another thing that jumps out is that both the TestStats and Caliper controller have fairly high churn. The Caliper controller has been growing fairly large as it has been doing double duty for user facing features and admin features, which should be split up. TestStats is admin controller code that also has been growing in size and should be split up into more isolated cases.

    churn results

    Churn gave me an idea of where might be worth focusing my effort. Diving in to the other metrics made it clear that the Caliper controller needed some attention.

    The Flog, Reek, and Roodi Scores for Caliper Controller:

    File Total score Methods Average score Highest score
    /app/controllers/caliper.rb 214 14 15 42

    reek before cleanup

    Roodi Report
    app/controllers/caliper.rb:34 - Method name "index" has a cyclomatic complexity is 14.  It should be 8 or less.
    app/controllers/caliper.rb:38 - Rescue block should not be empty.
    app/controllers/caliper.rb:51 - Rescue block should not be empty.
    app/controllers/caliper.rb:77 - Rescue block should not be empty.
    app/controllers/caliper.rb:113 - Rescue block should not be empty.
    app/controllers/caliper.rb:149 - Rescue block should not be empty.
    app/controllers/caliper.rb:34 - Method name "index" has 36 lines.  It should have 20 or less.
    
    Found 7 errors.
    

    Roodi and Reek both tell you about design and readability problems in your code. The screenshot of our Reek 'code smells' in the Caliper controller should show how it had gotten out of hand. The code smells filled an entire browser page! Roodi similarly had many complaints about the Caliper controller. Flog was also showing the file was getting a bit more complex than it should be. After picking off some of the worst Roodi and Reek complaints and splitting up methods with high Flog scores, the code had become easily readable and understandable at a glance. In fact I nearly cut the Reek complaints in half for the controller.

    Reek after cleanup

    Refactoring one controller, which had been quickly hacked together and growing out of control, brought it from a dizzying 203 LOC to 138 LOC. The metrics drove me to refactor long methods (52 LOC => 3 methods the largest being 23 LOC), rename unclear variable names (s => stat, p => project), move some helpers methods out of the controller into the helper class where they belong. Yes, all these refactorings and good code designs can be done without metrics, but it can be easy to overlook bad code smells when they start small, metrics can give you an early warning that a section of code is becoming unmanageable and likely prone to higher defect rates. The smaller file was a huge improvement in terms of cyclomatic complexity, LOC, code duplication, and more importantly, readability.

    Obviously I think code metrics are cool, and that your projects can be improved by paying attention to them as part of the development lifecycle. I wrote about metric_fu so that anyone can try these metrics out on their projects. I think metric_fu is awesome, and my interest in Ruby tools is part of what drove us to build Caliper, which is really the easiest way try out metrics for your project. Currently, you can think of it as hosted metric_fu, but we are hoping to go even further and make the metrics clearly actionable to users.

    In the end, yep, this is a bit of a plug for a product I helped build, but it is really because I think code metrics can be a great tool to help anyone with their development. So submit your repo in and give Caliper hosted Ruby metrics a shot. We are trying to make metrics more actionable and useful for all Ruby developers out, so we would love to here from you with any ideas about how to improve Caliper, please contact us.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on October 27th, 2009 by Dan in Development, Devver, Hacking, Misc, Ruby, Testing, Tools and tagged , , , , , .

  • Announcing Caliper

    by Avdi

    If you're anything like us, you recognize the usefulness of code quality metrics. But configuring metrics tools and linking them to your Continuous Integration system is a chore you may not have found time for. Here at Devver we're all about taking the pain out of common development chores. Which is why we're pleased to announce a new Devver service: Caliper.

    Caliper is the easy way to get code metrics - like cyclomatic complexity and code duplication - about your project. Just go to http://devver.net/caliper. Enter the public Git repository URL of a Ruby project. In a few moments, we'll give you a full set of metrics, generated by the awesome metric_fu gem.


    If your project is hosted on Github, we can even re-generate metrics automatically every time someone makes a commit. Just add the URL http://api.devver.net/github to your project's Post-Receive Hooks.

    Caliper is currently an Alpha product. We will be be rapidly adding features and refinements over the next few weeks. If you have a problem, a question, or a feature request, please let us know!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on October 9th, 2009 by Avdi in Devver and tagged , , , , , , , .

  • Announcing the Devver API (alpha version 0.1)

    by Ben

    Devver is great if you have a large test or spec suite that benefits from massive parallelism. But what if you have a project with fast tests and you just want to run them regularly? In this case, our existing service may be more than you need.

    To further our vision of enabling Ruby developers to easily and quickly run their tests in the cloud, we've recently released the very first version of a HTTP-based Devver API. Right now, it offers a single service: a GitHub compatible web hook which will cause Devver to do a continuous integration-style build of your project, and email you the results.

    The API is still in it's infancy but we already have some cool features:

    • Support for MySQL, PostgreSQL, and SQLite databases
    • A RubyGem installation system that (by default) uses your config/environment.rb and config/environments/test.rb files to install gems
    • An extremely flexible hooks system so you can customize the way we install gems, prepare your database, run your 'build' command, and notify you.

    We're releasing very early, so there are some rough spots (notably, the output is too verbose and the setup is too complicated). But we're also releasing often, so please let us know what you think and which features you'd like to see added.

    If you have a project on GitHub, please try out the API and send us feedback. We'd really appreciate it!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on September 16th, 2009 by Ben in Devver and tagged , .

  • Devver is now in public beta!

    by Ben

    We're very happy to announce that today we released our public beta!

    This is a big step forward for us and we're extremely excited about this release. Please try it out and give us feedback on our support site!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on August 17th, 2009 by Ben in Devver and tagged .

  • Devver is a sponsor of BizConf

    by Ben

    I'm happy to announce that Devver is one of the sponsors of BizConf. The event is shaping up to be a great one, so I'm very excited about attending.

    The presenter lineup looks great. Here are just a few of the talks that I'm looking forward to attending:

    Corey Haines - Why Agile Will Probably Fail You

    Jon "Lark" Larkowski - Getting Things Done

    Ian McFarland - Rails Economics and the ARC Model

    Check out the full list of speakers.

    If you're interested in attending, the bad news is that early bird pricing is over. The good news is that if you use the code DEVVER when registering, you'll get $1000 off your ticket price.

    If you do attend BizConf, please come find me to talk about getting started with Devver!

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on July 23rd, 2009 by Ben in Devver and tagged , .

  • Announcing Devver as a Lone Star Ruby Conference Sponsor

    by Dan

    We are very happy to be a sponsor of LSRC. I am especially excited because that means I get to attend the event. I am looking forward to getting a chance to meet another Ruby community as I have never been to Austin Texas, and it seems like there are a lot of exciting things going on with the Ruby community. Find me and come by to talk about Ruby, testing, or Devver. Devver is also currently hiring, so if you are attending the conference and interested in highly distributed Ruby systems, definitely come talk to us. It is great to get to participate in events like these and spend time with the amazing Ruby community which is so supportive of new ideas, good code and testing, and startups.

    Check out some of the great things that will be going on at Lone Star Ruby Conf this year.

    I am particularly excited about:

    • Mike Subelsky: Ruby for Startups: Battle Scars and Lessons Learned
    • Larry Diehl: Dataflow: Declarative concurrency in Ruby
    • Ian Warshak: Rails in the Cloud
    • Jeremy Hinegardner: Playing nice with others. -- Tools for mixed language environments.
    • Evan Light: TDD: More than just "testing"
    • Jake Scruggs: What's the Right Level of Testing?
    • Corey Donohoe, atmos: think simple
    • Pradeep Elankumaran: Fast and Scalable Front/Back-end Services using Ruby and XMPP
    • Danny Blitz: Herding Tigers - Software and the Art of War
    • Looking forward to meeting everyone in Austin, shoot me an email at dan@devver.net or message me on twitter @danmayer so we can meet up at the conference in person.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on July 20th, 2009 by Dan in Devver, Ruby and tagged .

  • Screencast: Setting up Devver on a non-Rails project

    by Ben

    In order to show how easy it is to configure Devver for a project, we've made a short screencast to walk you through the steps. We've used DataMapper as an example application. As you can see, it only takes a few minutes to set up Devver and then the specs complete in a fraction of the time. In fact, the whole process - setup and Devver run - takes less time than running 'rake spec'.

    In order to see the commands clearly, you'll want to enter full-screen mode. Or, if you prefer, you can download the high-quality version.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on July 9th, 2009 by Ben in Devver and tagged , , , .

  • Announcments! (via video)

    by Ben

    Our friend Andrew Hyde recently helped us film a short video of us announcing some of the recent developments here at Devver. Check it out!

    Devver Announces Funding from Andrew on Vimeo.

    Devver Caliper: Hosted metric_fu for your Ruby project.
    Get set up in under a minute

    Posted on July 8th, 2009 by Ben in Devver and tagged .