Return-Path: X-Original-To: apmail-hbase-dev-archive@www.apache.org Delivered-To: apmail-hbase-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8090E10DA9 for ; Fri, 22 Nov 2013 23:07:10 +0000 (UTC) Received: (qmail 28946 invoked by uid 500); 22 Nov 2013 23:07:09 -0000 Delivered-To: apmail-hbase-dev-archive@hbase.apache.org Received: (qmail 28891 invoked by uid 500); 22 Nov 2013 23:07:09 -0000 Mailing-List: contact dev-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list dev@hbase.apache.org Received: (qmail 28883 invoked by uid 99); 22 Nov 2013 23:07:09 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 22 Nov 2013 23:07:09 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of todd@cloudera.com designates 209.85.215.51 as permitted sender) Received: from [209.85.215.51] (HELO mail-la0-f51.google.com) (209.85.215.51) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 22 Nov 2013 23:07:03 +0000 Received: by mail-la0-f51.google.com with SMTP id ec20so1363679lab.24 for ; Fri, 22 Nov 2013 15:06:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:content-type; bh=9zdYcCTn0k4tICsS9i8usFQMueDVH54/1PaKf+LdCWU=; b=dlR2bU2uhtq1OAGtVGgplYSSSnY+LIWluPg+S962A/yaAFfaAKOW4QHx0eTnXPm3je kIylI82bDq8Fye4HqDS+MKhsR3sAtT4qKNXOmc+oqgdV718cig5bad+VlguckQfbp8P9 YhUgDHdsBKtwGnQoU+VwcTYUDWAnJuWYRyrMqpvpvQmt/XDctav5XVQkmvuK2CnkaYZz neph7o/KHW0FRFK2ceZgVWpLkvAbFr+8DcG5MpNosTI/4p466okS2EW28sE8MF8/KYFZ RFFr1fMQVO3yqDgzhvVfqgPP5ni+VQiiUOpOP8BOUUVK4bjzzGMGryqZOfkZ2aTXS2q/ dd9g== X-Gm-Message-State: ALoCoQk1RzVRALA0DlBwfvfzx6uOfRr0ArRY0jSiFvyC9dX45AylpJ81gBtx5Oazb7ndOOc6okaE X-Received: by 10.112.199.196 with SMTP id jm4mr18899lbc.59.1385161603349; Fri, 22 Nov 2013 15:06:43 -0800 (PST) MIME-Version: 1.0 Received: by 10.112.210.130 with HTTP; Fri, 22 Nov 2013 15:06:23 -0800 (PST) In-Reply-To: References: From: Todd Lipcon Date: Fri, 22 Nov 2013 15:06:23 -0800 Message-ID: Subject: Re: Adding frameworks and coding for testabilitywas [Re: Testing the fix for race condition between Compaction and StoreScanner.init] To: dev Content-Type: multipart/alternative; boundary=001a11c343ba53137b04ebcc11e5 X-Virus-Checked: Checked by ClamAV on apache.org --001a11c343ba53137b04ebcc11e5 Content-Type: text/plain; charset=ISO-8859-1 I haven't seen the particular "framework" in question, but I do think there's a continuum of reasonable choices here, ranging from full DI and using mocks/spys, to using AspectJ for AOP, to dding specific injections into the code at key points. I've experimented with probably the full range of options, and what I found to work best in HDFS was the addition of "FaultInjector" interfaces for each area of the code. For example: https://github.com/apache/hadoop-common/blob/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/CheckpointFaultInjector.java example usage: https://github.com/apache/hadoop-common/blob/trunk/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/TransferFsImage.java#L126 I see Jon's point that this litters the code with explicit injection points. However, I disagree that that's a bad thing. Seeing a call to FaultInjector.foo() in the code makes a future developer more wary of where they need to be careful -- and ensures that, if they change the design of that area of the code, that they need to consider the same faults as the original. Additionally, contrary to the DI approach (which typically involves splitting classes into bunches of smaller units), the changes for this type of fault injection are well-contained: they add a line here or there, but they don't affect the higher-level design of the code, so you're free to code in a way that is more understandable instead of ending up with CheckpointDownloadStrategyFactoryFactories or something. Just one guy's opinion :) -Todd On Fri, Nov 22, 2013 at 12:54 PM, Stack wrote: > On Wed, Nov 20, 2013 at 3:27 PM, Jonathan Hsieh wrote: > > > tl;dr if we are going to add new frameworks, please make them a separate > > patch. another attempt to bring up coding for testability/dep injection > > again. > > > > I've changed the subject because I really meant this to be a bigger > > discussion about setting up our code to be more testable and using > > conventions that allow us to do dependency injection (ala guava or in a > way > > we can use mockito) or deciding to to include this new-to-me > > InjectionHandler frameworks from the 89-fb branch. Porting HBASE-9949's > > testing code depended this Injector infrastructure that I found > > distasteful. > > > > This particular example smells funny and looked like another stovepiped > > framework to me -- > > 1) It added references and objects to our core code instead of having it > > only present for our tests. > > 2) This made the core code more cumbersome to read. > > 3) Initial version used a brittle convention. Initially, the injection > > point was identified by passing empty object array of particular size (0 > > size mean option 0, size 1 meant injection point 1, etc). Later changed > to > > a enum, As used in the 89-fb branch we have a new global pool of > unrelated > > enum/constant values that seemed brittle for further extension. > > > > > How did such a mess even get committed? > St.Ack > -- Todd Lipcon Software Engineer, Cloudera --001a11c343ba53137b04ebcc11e5--