Posts de July, 2008

[Rafael Silva Pereira] Generalizando os conceitos de Integração Contínua

Friday, July 25th, 2008

A utilização de processos de integração contínua no desenvolvimento de software, é hoje algo bastante corriqueiro em ambientes onde existe uma preocupação com a qualidade do código. A implementação de testes unitários e a execução dos mesmos de forma periódica, garante que o funcionamento de cada um dos componentes seja validado, o que impede a introdução de bugs, principalmente quando estamos falando do desenvolvimento de novas funcionalidades em uma aplicação já existente. Este conceito de integração contínua é tão importante para o processo de desenvolvimento, que por várias vezes me perguntei como poderíamos generaliza-lo para utilização em situações diferentes.

Quando conhecemos a complexidade dos processos de codificação de vídeos, nos deparamos com uma imensa quantidade de variáveis que podem interferir na qualidade do vídeo codificado, de modo que é praticamente impossível garantir que um determinado processo de codificação sempre irá gerar resultados satisfatórios. Além disso, fatores externos, como sistema operacional, hardware, etc, também influenciam nos resultados obtidos, seja na velocidade de codificação, seja na própria integridade do conteúdo.

Em ambientes de produção de vídeo em alta escala, é fundamental garantir que todas as variáveis que influenciam no processo de codificação estejam sob controle, de modo que os impactos de qualquer alteração sejam rapidamente identificados, antes que elas sejam efetivamente aplicadas no ambiente de produção. Se fizermos um paralelo com os processos de desenvolvimento de software, o que precisamos é exatamente o que a execução contínua de build e testes faz, ou seja, garante que não houve quebra de funcionalidades gerada por alterações no software.

Para exemplificar, podemos citar um processo de codificação com o Windows Media Encoder (Para quem não conhece, o Windows Media Encoder é um codificador WMV da Microsoft, bastante popular para quem usa Windows Media Video). Devido à uma alteração nas bibliotecas utilizadas pelo WME feita pela atualização do SP2 do Windows XP, podemos ter um aumento no tempo de codificação, além de alguns erros com arquivos específicos. Isto significa que a simples atualização do Service Pack do sistema operacional pode influenciar bastante no processo de codificação. Se, neste cenário, temos um processo de codificação contínuo, então essas diferenças seriam facilmente identificadas, antes que esta atualização fosse efetivamente aplicada.

Entretanto, ter simplesmente um processo de codificação que roda constantemente não é o suficiente para garantirmos a integridade de um ambiente. É de fundamental importância ter uma quantidade grande de mídias de diferentes perfis, ou seja, ter diversas mídias, de diversas durações, com vários tipos de conteúdo distintos e de várias fontes diferentes. Desta forma, com uma biblioteca de conteúdo diversificada e com um processo de verificação contínuo, temos como analisar de forma eficiente um ambiente de codificação.

Outro ponto importante no processo de codificação de vídeos é que a maioria deles não é “binário”, ou seja, se você codificar o mesmo vídeo 100 vezes, você não terá a mesma saída 100 vezes. Por isso, além de codificar continuamente diversos vídeos diferentes, é bastante importante codificar o mesmo vídeo repetidamente, sendo que este vídeo deve ser escolhido dentre um universo por ser aquele que apresenta a maior taxa de erros. Desta forma, estamos introduzindo mais uma validação de integridade.

Não conheço nenhuma ferramenta pronta para execução de testes desta natureza, porém, é relativamente simples escrever uma. Claro que se você deseja um output gráfico, em tempo real, é necessário dedicar um tempo razoável para isto, mas nada que não seja justificado pelos ótimos benefícios obtidos com esta prática.

[Rafael Silva Pereira] Generalizando os conceitos de Integração Contínua

Friday, July 25th, 2008

A utilização de processos de integração contínua no desenvolvimento de software, é hoje algo bastante corriqueiro em ambientes onde existe uma preocupação com a qualidade do código. A implementação de testes unitários e a execução dos mesmos de forma periódica, garante que o funcionamento de cada um dos componentes seja validado, o que impede a introdução de bugs, principalmente quando estamos falando do desenvolvimento de novas funcionalidades em uma aplicação já existente. Este conceito de integração contínua é tão importante para o processo de desenvolvimento, que por várias vezes me perguntei como poderíamos generaliza-lo para utilização em situações diferentes.

Quando conhecemos a complexidade dos processos de codificação de vídeos, nos deparamos com uma imensa quantidade de variáveis que podem interferir na qualidade do vídeo codificado, de modo que é praticamente impossível garantir que um determinado processo de codificação sempre irá gerar resultados satisfatórios. Além disso, fatores externos, como sistema operacional, hardware, etc, também influenciam nos resultados obtidos, seja na velocidade de codificação, seja na própria integridade do conteúdo.

Em ambientes de produção de vídeo em alta escala, é fundamental garantir que todas as variáveis que influenciam no processo de codificação estejam sob controle, de modo que os impactos de qualquer alteração sejam rapidamente identificados, antes que elas sejam efetivamente aplicadas no ambiente de produção. Se fizermos um paralelo com os processos de desenvolvimento de software, o que precisamos é exatamente o que a execução contínua de build e testes faz, ou seja, garante que não houve quebra de funcionalidades gerada por alterações no software.

Para exemplificar, podemos citar um processo de codificação com o Windows Media Encoder (Para quem não conhece, o Windows Media Encoder é um codificador WMV da Microsoft, bastante popular para quem usa Windows Media Video). Devido à uma alteração nas bibliotecas utilizadas pelo WME feita pela atualização do SP2 do Windows XP, podemos ter um aumento no tempo de codificação, além de alguns erros com arquivos específicos. Isto significa que a simples atualização do Service Pack do sistema operacional pode influenciar bastante no processo de codificação. Se, neste cenário, temos um processo de codificação contínuo, então essas diferenças seriam facilmente identificadas, antes que esta atualização fosse efetivamente aplicada.

Entretanto, ter simplesmente um processo de codificação que roda constantemente não é o suficiente para garantirmos a integridade de um ambiente. É de fundamental importância ter uma quantidade grande de mídias de diferentes perfis, ou seja, ter diversas mídias, de diversas durações, com vários tipos de conteúdo distintos e de várias fontes diferentes. Desta forma, com uma biblioteca de conteúdo diversificada e com um processo de verificação contínuo, temos como analisar de forma eficiente um ambiente de codificação.

Outro ponto importante no processo de codificação de vídeos é que a maioria deles não é “binário”, ou seja, se você codificar o mesmo vídeo 100 vezes, você não terá a mesma saída 100 vezes. Por isso, além de codificar continuamente diversos vídeos diferentes, é bastante importante codificar o mesmo vídeo repetidamente, sendo que este vídeo deve ser escolhido dentre um universo por ser aquele que apresenta a maior taxa de erros. Desta forma, estamos introduzindo mais uma validação de integridade.

Não conheço nenhuma ferramenta pronta para execução de testes desta natureza, porém, é relativamente simples escrever uma. Claro que se você deseja um output gráfico, em tempo real, é necessário dedicar um tempo razoável para isto, mas nada que não seja justificado pelos ótimos benefícios obtidos com esta prática.

[Claudio Figueiredo] ASP.NET MVC Preview 4 Released

Wednesday, July 16th, 2008
  1. Read the Title
  2. Grab while it’s hot

Cheers,

[Guilherme Cirne] Implementando uma fluent interface para um webservice REST com method_missing

Sunday, July 13th, 2008

Nesse post vou mostrar como usar o method_missing do ruby para implementar uma fluent interface em um cliente de um webservice REST. Vamos supor um webservice imaginário com recursos que podem ser acessados nas seguintes URLs:

/recurso/id

/recurso/doTipo/algumTipo

Queremos que um cliente ruby para esse webservice forneça a seguinte fluent interface para acesso às URLs acima:


WebService.new.recurso(1).get

WebService.new.recurso.do_tipo(algumTipo).get

Uma maneira mais tradicional de se implementar esse cliente seria algo como:


require 'net/http'
require 'uri'

class WebService

  def initialize
    @url = String.new
  end

  def recurso(id = nil)
    @url << '/recurso'
    @url << "/#{id}" unless id.nil?
    self
  end

  def do_tipo(tipo)
    @url << "/doTipo/#{tipo}"
    self
  end

  def get
    response = Net::HTTP.get_response(URI.parse("http://localhost:8080#{@url}"))
    response.value
    response.body
  end

end

Repare que nos métodos recurso e do_tipo é retornado self, possibilitando o encadeamento dos métodos na fluent interface. No método get, response.value sobe uma exceção se o retorno do webservice for qualquer coisa diferente de 200 e response.body retorna o corpo do response.

Utilizando o method_missing a implementação fica bem mais simples e elegante:


require 'net/http'
require 'uri'

class WebService

  def initialize
    @url = String.new
  end

  def get
    response = Net::HTTP.get_response(URI.parse("http://localhost:8080#{@url}"))
    response.value
    response.body
  end

  def method_missing(metodo, *args)
    @url << "/#{camel_case(metodo)}"
    @url << "/#{args[0]}" if args.length > 0
    self
  end

  private

  def camel_case(metodo)
    primeira = true
    metodo.to_s.split('_').map {|palavra|
      if primeira
        primeira = false
        palavra
      else
        palavra.capitalize
      end
    }.join
  end

end

Uma característica interessante da implementação com method_missing é que ela serve para qualquer URL de qualquer recurso que já exista ou que venha a ser criada (obviamente isso só vale se houver a padronização entre a URL e a fluent interface).

[Claudio Figueiredo] ASP.Net MVC ActionFilters

Sunday, July 13th, 2008

I’m a lame blogger, I know. There’s been more than two years that my friend Heynemann has been teasing me to post more, and it’s starting to happen more naturally these times. The reason that I blog less than I’d wish for is that I’m crazy about coding. That’s where I tend to focus most of my time, but I’ll keep posting more frequently now. The reasoning behind this introduction is to assure all my three readers (you know who you are lol), that my series on .Net MVC will be continuing soon.

Action Filters - Why and How?

Action Filters are .Net MVC native way of adding intercepting capabilities to your application. It’s a non-imperative way of adding some AOP to your Controller’s Actions without resorting to AOP or IoC frameworks.

It’s a sweet move on the part of the development team, and It’s something that makes SoC and extensibility in .Net MVC very easy to implement.

Well, since the first time I’ve read about it, I knew it would be a perfect fit to integrate with ValEver.

ValEver (short for Validation Everywhere) was one of the neatest pieces of code ever produced by Bernardo and I had the pleasure of developing its integration with Windsor Container some months ago.

I’ll try to give some examples here on how to use ActionFilters through implementing integration with ValEver and check on the benefits of this happy union. :D

ActionFilters provide a declarative way to access the executing context prior to, and following, the execution of an action.

It has a simple yet meaningful contract:

public abstract class ActionFilterAttribute : Attribute, IActionFilter
{
 
    // Methods
    protected ActionFilterAttribute();
    public virtual void OnActionExecuted(ActionExecutedContext filterContext);
    public virtual void OnActionExecuting(ActionExecutingContext filterContext);
    public virtual void OnResultExecuted(ResultExecutedContext filterContext);
    public virtual void OnResultExecuting(ResultExecutingContext filterContext);
 
    // Properties
    public int Order { get; set; }
}

Most methods are self explanatory but the important ones in what I’m trying to achieve are OnActionExecuting and the ActionExecutingContext.

That’s the Pre handler of a Controller’s Action call. Through it you can reach the Context and interact with it.

First thing I did, as any good developer should do, was a test. And so it came:

[ValEverActionFilter]
[ValidationShouldThrow]
public ActionResult Index([Required("Supply a valid parameter")]string parameter1) {
    return View();
}

The ValidationShouldThrow and Required(“Supply a valid parameter”)] attributes are native from ValEver. The first being a marker to control behaviour, the second being ‘The’ validation of a parameter.

And from this test came my custom ValEverActionFilter:

public class ValEverActionFilterAttribute : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        base.OnActionExecuting(filterContext);
    }

This small piece of code is all that’s needed. Besides the business logic, which will be added later, all I need are the parameter values . Interestingly we have them. The neat trick here is the context.

The ActionExecutingContext allows us to direct access to info such as …

//The calling Action
public MethodInfo ActionMethod { get; private set; }
 
//The parameters and it's values
public IDictionary<string, object> ActionParameters { get; private  set; }
 
//The request HttpContext 
public HttpContextBase HttpContext { get; internal set; }
 
//Any data regarding the Routing used in the call
public RouteData RouteData { get; internal set; }

… being able to manipulate almost anything inside the call’s context.

Then again, I settled to test. But this time I need an integrated test between the Controller Action and the Validation through the call of ValEverActionFilter.

It happens that only calling the Action is not enough. And it makes sense. The controller is not so special alone after all. The ActionFilter calling is done on the Handler instantiation on ASP.NET.
“- So, no problem. How hard could it be?” TM

After lot of googling I found how hard it was. There’s no out-of-the-box solution for this kind of test. So I set to make mine and it came as:

[Test]
public void ShouldThrowOnInvalidParameters() {
 
    TestingController controller = new TestingController();

 
    Assert.Throws<ValitationFailedException>(() => 
        controller.InvokeActionWithFilters<TestingController>(p 
            => p.Index(string.Empty)));
}

The InvokeActionWithFilters Extension Method mimics what the ASP.NET does. Supplying defaults and calling the ActionFilter’s hooked events in the right time with the right context.

Then I just had to write the business logic to my filter, and make tests go green.

public class ValEverActionFilterAttribute : ActionFilterAttribute {
    public override void OnActionExecuting(ActionExecutingContext filterContext) {
 
        var methodInfo = filterContext.ActionMethod;
 
        AddValidationParameters(filterContext, methodInfo);
 
        bool isValid = ValidationContext.Validate(filterContext.Controller) &&
                                     ValidationContext.ValidateArguments(methodInfo);
 
        ThrowIfRequiredByDecoration(isValid, methodInfo);
 
        base.OnActionExecuting(filterContext);
    }

Nothing more had to be done to have it interacting with the method call.
The filterContext.ActionMethod contains all the information needed. Parameters and it’s values too.

Conclusion

So, despite the little trouble testing the ActionFilters with the call’s context, it was easy extend and interact with one of the core aspect of a MVC framework and, better yet, keeping the concerns apart. Just some other cool things you can do with ActionFilters:

  • Cancel Action Execution
  • Interact with HttpContext
  • Override/fill parameters values
  • Set manually your own ActionResult

This opens so many possibilities that it makes me glad to see development going in this direction and delivering such good feats.

The full code of the sample application can be found here.

Cheers.

[Claudio Figueiredo] Lack of Tests

Wednesday, July 9th, 2008

You might not hear me, nor Mr. Beck or anyone, but certainly you’ll hear Dart Vader:

LackOfTests

[Claudio Figueiredo] When life should imitate fiction :)

Saturday, July 5th, 2008

Somewhere, over the rainbow…

[Claudio Figueiredo] When fiction imitates life…

Saturday, July 5th, 2008

That’s how one feels when he’s reprehended for Unit Testing.