6 Replies Latest reply on Feb 2, 2011 4:35 AM by adinn

    @BMUnitConfig

    starksm64

      Hello,

       

      I just started playing around with byteman today after seeing the new bmunit contribution, and jumped into testing some things using that. One thing I immeaditely wanted was to configure some of the byteman Installer system properties from an annotation on the unit test class rather than having to set this up inside of the ide junit configuration. Properties like:

       

      org.jboss.byteman.contrib.bmunit.script.directory

      org.jboss.byteman.contrib.bmunit.agent.port

      org.jboss.byteman.contrib.bmunit.agent.host

      org.jboss.byteman.contrib.bmunit.verbose

      org.jboss.byteman.verbose

      org.jboss.byteman.debug

      org.jboss.byteman.home

       

       

      were those that first came to mind as I needed to search the code to see what things I could set to debug what was going on with bmunit/byteman itself. Something like the following class level annotation that would be used in the BMUnit class when it calls to the Installer:

       

      /*
       * JBoss, Home of Professional Open Source
       * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
       * as indicated by the @authors tag. All rights reserved.
       * See the copyright.txt in the distribution for a
       * full listing of individual contributors.
       *
       * This copyrighted material is made available to anyone wishing to use,
       * modify, copy, or redistribute it subject to the terms and conditions
       * of the GNU Lesser General Public License, v. 2.1.
       * This program is distributed in the hope that it will be useful, but WITHOUT A
       * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
       * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
       * You should have received a copy of the GNU Lesser General Public License,
       * v.2.1 along with this distribution; if not, write to the Free Software
       * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
       * MA  02110-1301, USA.
       */
      package org.jboss.byteman.contrib.bmunit;
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      /**
       * Unit test level configuration of byteman properties
       *
       * @author Scott stark (sstark@redhat.com) (C) 2010 Red Hat Inc.
       */
      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE})
      public @interface BMUnitConfig {
      
         /**
          * org.jboss.byteman.home
          * System property used to idenitfy the location of the installed byteman release.
          */
         String bytemanHome() default "";
         /**
          * org.jboss.byteman.contrib.bmunit.script.directory
          * property which identifies the directory from which to start searching
          * for rule script. If unset the current working directory of the test is used.
          */
         String scriptDirectory() default "";
         /**
          * org.jboss.byteman.contrib.bmunit.agent.port
      ...
          */
         int agentPort() default -1;
         /**
          * org.jboss.byteman.contrib.bmunit.agent.host
          */
         String agentHost() default "";
         /**
          * org.jboss.byteman.contrib.bmunit.verbose
          */
         boolean isBmunitVerbose() default false;
         /**
          * org.jboss.byteman.verbose
          */
         boolean isBytemanVerbose() default false;
         /**
          * org.jboss.byteman.debug
          */
         boolean isBytemanDebug() default false;
      
      }
      
      

       

      If that sounds like a good idea, I'll create an issue and attach a patch to it for these changes.

        • 1. @BMUnitConfig
          adinn

          Scott Stark wrote:

           

          . . .

           

          If that sounds like a good idea, I'll create an issue and attach a patch to it for these changes.

           

          That sounds like a fabulous idea. Would you like commit rights? :-)

           

          There are a couple of small details here which merit a little dsiscussion.

           

          Two of the agent properties (port, host) are one shot values as far as the agent listener side of the upload/unload process is concerned. Once the agent has been loaded it cannot be unloaded or reloaded. So, if two tests specify different values for these properties it would not be possible to reload the agent using trhe second host and port (well, anything is possible but providing a way for a loaded agent to swap from its current port to a new port is tricky and, potentially, raises security issues). The values in the second annotation could be ignored i.e. rules could just be uploaded/unloaded using the parameters specified in the first annotation -- that sounds lilke a recipe for confusion. Alternatively, they could be used to determine which communication path to use from the client side but not from the agent listener side. This would normally mean that rules fail to upload but, if the configuraton is really wrong, it might just upload the rules to some other JVM. I think this probably just needs careful documentation.

           

          All of the other properties can be easly made mutable so that successive tests can reset them (the agent listener already provides support for this). However, with the current implementation mutability needs to be enabled at agent load because it can hurt performance. In particular, allowing verbose mode to be reset means that many operations in the agent runtime will include conditional branches (If it is never set then the branches are pretty much guaranteed to be JIT-compiled out). That's not an issue in most cases but it could be significant for performance or multithreaded tests. A way round this is to provide another annotation field property isReconfigurationEnabled() default true which will can be set to false in tests where performance really matters. Obviously, this would also have to be a one-shot setting.

           

          Finally, it may be useful to add another property isAgentLoadEnabled() defalt true. Setting this would stop BMUnit loading the agent into the current JVM. This is useful if e.g. the test is driving a remote app server and the rules need to be uploaded to the app server JVM.

          • 2. @BMUnitConfig
            starksm64

            Andrew Dinn wrote:

             


            That sounds like a fabulous idea. Would you like commit rights? :-)

            Sure, I have other plans for cloud work

             

             

            Andrew Dinn wrote:

             

            Two of the agent properties (port, host) are one shot values as far as the agent listener side of the upload/unload process is concerned. Once the agent has been loaded it cannot be unloaded or reloaded. So, if two tests specify different values for these properties it would not be possible to reload the agent using trhe second host and port (well, anything is possible but providing a way for a loaded agent to swap from its current port to a new port is tricky and, potentially, raises security issues). The values in the second annotation could be ignored i.e. rules could just be uploaded/unloaded using the parameters specified in the first annotation -- that sounds lilke a recipe for confusion. Alternatively, they could be used to determine which communication path to use from the client side but not from the agent listener side. This would normally mean that rules fail to upload but, if the configuraton is really wrong, it might just upload the rules to some other JVM. I think this probably just needs careful documentation.

            Got it. One of the areas I want to look into is how byteman could fit into the AS7 domain controller as a debugging tool and even monitoring tool that has it's rules embeded into the domain model. I'll discuss that more as I look into it.

             

             

            Andrew Dinn wrote:


            All of the other properties can be easly made mutable so that successive tests can reset them (the agent listener already provides support for this). However, with the current implementation mutability needs to be enabled at agent load because it can hurt performance. In particular, allowing verbose mode to be reset means that many operations in the agent runtime will include conditional branches (If it is never set then the branches are pretty much guaranteed to be JIT-compiled out). That's not an issue in most cases but it could be significant for performance or multithreaded tests. A way round this is to provide another annotation field property isReconfigurationEnabled() default true which will can be set to false in tests where performance really matters. Obviously, this would also have to be a one-shot setting.

             

            Finally, it may be useful to add another property isAgentLoadEnabled() defalt true. Setting this would stop BMUnit loading the agent into the current JVM. This is useful if e.g. the test is driving a remote app server and the rules need to be uploaded to the app server JVM.

            Ok, I'll add these and test them out.

             

            Thanks

            • 3. @BMUnitConfig
              adinn

              Hi Scott,

               

              Thanks very much for offering to contribute. I have added you as a developer in the svn admin file using id scott.stark@jboss.org.

               

              One other thing I noticed which you will need to look at is the static init in class BMUnit which performs  the agent load. If you want the load to respect BMUnitConfig settings then you will need to find some way of avoiding triggering this static init until after the config settings on the first test class have been made available (the static init is currently triggered by the first load request).

               

              Also, I have just now added support for TestNG tests. Whatever config setup you add to the JUNit Runner class (BMUnitRunner) will also need to be invoked by the TestNG runner class (BMNGRunner). You should be able to  cut and paste the same code from the former into the latter class but I'm happy to do it if you don't  know TestNG.

               

              Using Byteman in the domain controller sounds like a great idea. I'll be very glad to help you do this if and where help is needed.

               

              Happy hacking!

              • 4. @BMUnitConfig
                starksm64

                Thanks, I definitely saw that some refactoring was going to be needed to update the static block loading the agent. For now I'll try to be minimalistic in changes. I will take a look at the TestNG runner as well.

                • 5. @BMUnitConfig
                  starksm64

                  I have this basically tested out in the following branch:

                  https://svn.jboss.org/repos/byteman/branches/BYTEMAN-148

                   

                  I ended up changing the org.jboss.byteman.agent.install.Install class to return the Install instance, and exposes the VirtualMachine system properties for testing for example. I'll work on more tests as I try to integrate this into some AS7 related work.

                  • 6. @BMUnitConfig
                    adinn

                    Thanks, Scott. That's looking great.

                     

                    You may possibly find some conflicts on merge. In order to simplify maven based testing I had to tweak Install to locate the agent jar from the class path via Sys property java.class.path if BYTEMAN_HOME and org.jboss.bteman.home are unset ( https://issues.jboss.org/browse/BYTEMAN-149). Apologies if this causes you any grief.