SELECT CAST (power(CrazyIdeas, Curiosity) * (RealLifeExperience + MyMistakes)) / FreeTime) AS VARCHAR(MAX)) FROM MyBrain WITH (NOLOCK, INDEX('idx_Neuron')) WHERE ThingsIThinkIKnow in ('SQL Server', 'DB2', '.NET', 'Cloud')
quinta-feira, 29 de outubro de 2009
Mande sua pergunta para o PASS!!
Amanhã eu vou para SP e depois embarco para Seattle, onde vou participar do PASS Summit 2009, evento focado no SQL Server. Minha meta é conseguir blogar um pouco sobre o evento e o que eu estou assistindo, para trazer um pouco do que verei para o resto da comunidade.
O site oficial do evento é esse aqui: http://summit2009.sqlpass.org
O evento em si acontece entre terça e quinta, mas eu também vou participar da pré e pós-conferência, passando o dia inteiro com...
Segunda: Kalen Delaney - Care and feeding of the transaction log
Sexta: Paul Randal e Kimberly Tripp - Disaster recovery: tips, tricks and techniques.
Mas o que significa o título do post "Mande sua pergunta para o PASS"?
Como eu estarei em contato com uns monstros do SQL Server e terei mais tempo para pensar sobre questões relacionadas ao SQL Server, será uma boa hora para responder perguntas mais difíceis sobre o funcionamento do nosso queridinho. Então se você quer saber de algo, deixe aqui seu comentário!
Outra coisa que devo comentar: na minha opinião, eventos como o PASS são imperdíveis para profissionais de SQL Server e participar de um evento como esse faz a pessoa amadurecer bastante e perceber o quanto podemos nos aprimorar.
Realmente gostaria de ver um grupo maior indo comigo no próximo ano e, com um pouco de controle e planejamento, não é nada de outro mundo. Será que vale a pena o evento? Faz o seguinte, dá uma olhada na grade do Summit e depois me conta: http://summit2009.sqlpass.org/LinkClick.aspx?fileticket=475oJ4TOQFQ%3d&tabid=68
Eu ia fazer uma enquete para vocês escolherem uma sessão para eu assistir, mas acho que não vai dar ibope, então caso sejam feitas perguntas e haja muito interesse sobre um tema específico, quem sabe eu mudo minha grade para tentar respondê-las...
Espero voltar em breve ao meu blog, assim que me organizar por lá. E para essa viagem longa vou levar o SQL Server 2008 Internals para me fazer companhia... Geek é geek e vice-versa (lembrando o artilheiro Jardel!).
E para variar, parece que vou pegar um friozinho com chuva em Seattle: http://www.weather.com/weather/tenday/USWA0395?from=month_topnav_undeclared
[]s
Luciano Caixeta Moreira - {Luti}
Chief Innovation Officer
Sr. Nimbus Serviços em Tecnologia Ltda
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
quarta-feira, 28 de outubro de 2009
Java vs .NET - Material e comentários
Analisando o que eu consegui assistir, o evento foi bem interessante, com ambos os lados focados em tecnologia e não em jogar pedra no outro, mas sempre sai uma faísca, que controlada é saudável. O público foi bastante eclético, com muitos estudantes e profissionais de TI, o que adiciona um ingrediente ao desafio, pois o apresentador têm que achar um meio termo para sua palestra, senão um dos grupos serão implicitamente convidados a tirar uma soneca.
Acho que a minha apresentação foi legal e o público gostou, no início eu estava com dificuldade para falar bem (tenho que me lembrar de comer menos antes de uma palestra! hahaha), mas no fim a coisa se ajeitou e nenhuma demo deu errado. Depois que eu falei o Marcelo, um camarada muito gente fina por sinal, falou com propriedade sobre a plataforma Java, onde pude notar uma série de semelhanças e dificuldades que todos enfrentamos, fortalecendo minha idéia de que ambas as tecnologias são boas, e nós profissionais de TI é que estamos estragando a brincadeira quando usamos mal a tecnologia.
Duas coisas me marcaram no evento:
1 - A falta de perguntas no debate! Eu achei que ia chover perguntas no fim das apresentações e aconteceu o contrário, no meu caso somente foram 3 perguntas. Isso foi muito chato.
2 - Os palestrantes de Java fazem poucas demonstrações. Eu sei que existe uma cultura interessante com eles, de discutirem o JCP, entender em qual versão está o que e quais frameworks (dos N) possuem qual recurso, mas poxa, uma demo sempre cai bem para materializar o que está sendo dito para o público.
A segunda parte do evento acontecerá no dia 07 de novembro, mas não poderei participar pois estarei viajando. De qualquer forma, fica aqui o convite.
Quem quiser minha apresentação, baixe aqui.
Valeu muito participar do evento, encontrar os amigos e conhecer novos profissionais e universitários...
[]s
Luciano Caixeta Moreira - {Luti}
Chief Innovation Officer
Sr. Nimbus Serviços em Tecnologia Ltda
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
SQLServerDay - 12 horas de SQL Server
No dia 07 de novembro vai rolar o SQLServerDay, com doze apresentações de uma hora sobre os mais variados temas, com muitos rostos conhecidos pela comunidade e que conhecem bastante do SQL Server. Para mais informações acessem o site (http://www.sqlserverday.com.br/default.html) ou a comunidade (http://sqlserverday.ning.com/).
Será que eu vou palestrar? NÃO!! Acredita?
Não foi por falta de vontade ou convite, mas infelizmente no sábado da realização do evento (também dia da segunda parte do evento Java versus .NET em Brasília) eu estarei voltando do PASS, evento de SQL Server que pariticiparei na semana que vêm e, a menos que eu possa transmitir do avião uma sessão, não vai rolar. :-)
Pelo menos estamos chamando de PRIMEIRO SQLServerDay, quem sabe nos outros eu não apareço.
Bom, o jeito vai ser assistir TODAS as gravações depois, mas tenho que adimitir que estou muito curioso para ver duas sessões: "Entenda porque o Query Optimizer é mais esperto que você" e "Analise de Desempenho utilizando as Estatísticas de Espera".
Adorei o título do primeiro! Pura verdade e ainda têm desenvolvedor que se acha melhor que o query optimizer...
[]s
Luciano Caixeta Moreira - {Luti}
Chief Innovation Officer
Sr. Nimbus Serviços em Tecnologia Ltda
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
terça-feira, 27 de outubro de 2009
Testes de unidade em aplicações multi-thread
Vamos ao nosso cenário básico: imagine uma classe responsável por disparar alguns workers em background de acordo com a tarefa que cada um deve executar. Esses procedimentos por si geram notificações através de eventos que podem ser tratados por outras classes da sua solução. Nada demais, o código para isso (bem simplificado) poderia ser assim:
Por simplicidade deste exemplo eu faço um Join() da thread criada, esperando o fim da execução, para deixar esse exemplo bem controlado, mas na aplicação de verdade isso é diferente.
public struct InfoTarefa
{
public string Info;
public DateTime horaExecução;
}
public class NegocioTeste
{
public void ExecutaTarefa(object informação)
{
InfoTarefa tarefa;
tarefa.Info = (string)informação;
tarefa.horaExecução = DateTime.Now;
if (TarefaCompleta != null)
TarefaCompleta(tarefa);
}
public delegate void NotificarTarefaCompleta(InfoTarefa tarefa);
public event NotificarTarefaCompleta TarefaCompleta;
}
public class ThreadEmBackground
{
public Listtarefas;
private NegocioTeste negocio;
public ThreadEmBackground(NegocioTeste n)
{
negocio = n;
}
public void ProcessaTarefas()
{
foreach (string tarefa in tarefas)
{
Thread t = new Thread(negocio.ExecutaTarefa);
t.Start(tarefa);
t.Join();
}
}
}
Para testar o código acima basta fazermos o setup correto das pré-condições, colocando as verificações do resultado na rotina de tratamento do evento TarefaCompleta.
Mas se a verificação falhasse no tratamento do nosso evento, que acontece em outra thread, olhe na figura abaixo o que veríamos:
[TestMethod]
public void TesteBásico()
{
//SETUP
Listtarefas = new List ();
tarefas.Add("Tarefa 01");
NegocioTeste negocio = new NegocioTeste();
ThreadEmBackground gerenteThreads = new ThreadEmBackground(negocio);
gerenteThreads.tarefas = tarefas;
negocio.TarefaCompleta += RecebeInfoTarefa;
Assert.AreEqual(1, gerenteThreads.tarefas.Count);
// Execução do curso básico
gerenteThreads.ProcessaTarefas();
}
public void RecebeInfoTarefa(TestesMultiThread.InfoTarefa tarefa)
{
Assert.AreEqual("Tarefa 01", tarefa.Info);
Assert.IsTrue(tarefa.horaExecução > DateTime.Now.AddMinutes(-1));
}
Um Error aparece no lugar do Failed, com um ícone de warning (?!) e a mensagem “The agent process was stopped while the test was running”. Se clicarmos duas vezes em cima do Error para analisar o que aconteceu (ação já automática com a falha usual do assert), a mesma mensagem será exibida, o que não ajuda em nada (no caso do Failed vemos a stack trace).
Aí você descobre que deve clicar em “Test run error” para ver a stack trace, onde conseguirá a informação “One of the background threads threw exception: Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Assert.Fail failed. Problema na validação”.
Isto é, por se tratar de uma thread em background, a maneira como o Visual Studio trata as verificações é diferente do comportamento usual, o que eu achei ruim. Isso mata alguém, não vejo maiores problemas, mas fico imaginando se trará algum impacto durante a automação dos testes ou em momentos diferentes, o que me deixa um pouco inseguro.
Outra coisa que eu tentei através do Visual Studio e não consegui ver uma maneira fácil (a não ser codificar), foi a possibilidade de executar o testes orientando o VS para disparar várias threads de uma só vez, me ajudando a testar condições de corrida.
Para ser super sincero, pode ser que o Visual Studio tenha recursos nessa área de testes para aplicações multi-thread, mas em algumas pesquisas rápidas que fiz não encontrei muitas referências e um funcionário da MS diz no fórum que “Nós não temos uma ótima história para contar sobre aplicações multi-threaded”. Em: http://social.msdn.microsoft.com/Forums/en-US/vststest/thread/c19e9ba8-52db-4970-99a4-04468206baf6/
Ainda vou explorar o DevCenter de computação paralela (http://msdn.microsoft.com/en-us/concurrency/bb895950.aspx) e o único recurso que eu achei para esse cenário, o projeto CHESS (http://research.microsoft.com/en-us/projects/chess/).
Para fechar o artigo: Com os computadores pessoais entrando na era dos multi-cores e todo mundo falando da necessidade de termos aplicações que aproveitem de verdade esses recursos (e até a GPU), espero que o Visual Studio traga boas novas nessa área e ajude os desenvolvedores, o que acredito que acontecerá.
Se você tiver alguma dica ou experiência para compartilhar, estou ansioso para ouvi-lo!
Baixe o PDF e código fonte aqui.
[]s
Luciano Caixeta Moreira - {Luti}
Chief Innovation Officer
Sr. Nimbus Serviços em Tecnologia Ltda
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
segunda-feira, 26 de outubro de 2009
Testes de unidade com deployment de arquivos
Olá pessoal, vamos de Visual Studio hoje.
Imagine um cenário bem comum: Estamos desenvolvendo um projeto que manipula arquivos e, para ajudar o desenvolvimento, você cria uma classe utilitária que lê do arquivo de configuração qual é o repositório local (diretório) onde os arquivos são armazenados. Essa classe auxiliar será utilizada por toda aplicação, então não existirá somente para testes. Exemplo de código abaixo:
public class Configuração
{
private static string repositórioArquivos;
static Configuração() {
repositórioArquivos = ConfigurationManager.AppSettings["RepositórioArquivos"];
}
public static string RepositórioArquivos {
get { return repositórioArquivos; }
}
}
public void RenomearArquivo(string nomeArquivo, string novoNomeArquivo) {
string repositório = Configuração.RepositórioArquivos;
File.Move(Path.Combine(repositório, nomeArquivo), Path.Combine(repositório,
novoNomeArquivo));
}
Antes ou depois de codificar a classe, você desenvolve alguns testes para testar seu componente, então para tudo funcionar corretamente você adiciona ao seu projeto de testes um arquivo App.Config e colocar uma entrada no AppSettings, que será lida pelo auxiliar de configuração:
public void TesteCenárioUsoBásico() {
// Pré-condições
Assert.IsTrue(File.Exists(Path.Combine(
TestesComArquivos.Configuração.RepositórioArquivos, "arquivoqualquer.txt")));
TestesComArquivos.ClasseNegocio negócio = new TestesComArquivos.ClasseNegocio();
negócio.RenomearArquivo("arquivoqualquer.txt", "novoarquivotexto.txt");
// Pós-condições
Assert.IsTrue(File.Exists(Path.Combine(
TestesComArquivos.Configuração.RepositórioArquivos, "novoarquivotexto.txt")));
}
Execute o projeto (em anexo a este artigo) e tudo funcionará perfeitamente. Quer dizer, mais ou menos, pois aqui temos alguns problemas:
1 - Depois que você executar esse teste, o arquivo estará renomado e a próxima execução vai falhar. Você corrige isso escrevendo direito as pré-condições e setup do seu teste. Por simplicidade eu deixarei como está, ok?
Tudo isso funciona corretamente se você está desenvolvendo sozinho, mas e se houver uma equipe junto com você?
2 - Em primeiro lugar, os arquivos não serão levados juntos com o projeto, então se alguém adiciona outro arquivo para teste, o que você faz? Isso garoto, adicione os arquivos ao projeto de teste, para todos os desenvolvedores terem acesso ao distinto quando pegarem uma nova versão do projeto.
3 - (Um problema de verdade) Cada desenvolvedor pode definir um diretório local diferente para seu workspace de trabalho, então se um desenvolvedor colocar os arquivos da solução em outro diretório e mudar o App.Config, quando você pegar a última versão do projeto no TFS, bye bye testes!
Uma maneira de "resolver" isso é ficar mudando o App.Config para cada desenvolvedor ou então padronizar o diretório local para o seu projeto, mas é um gato MUITO feio. Concorda? E se houverem builds diários, você vai fazer o quê? Como resolvemos isso?
- Adicione ao seu projeto o diretório "Arquivos" e coloque lá dentro o famoso "arquivoqualquer.txt". Lembre de marcar a opção do arquivo "Copy to output directory" com "Copy if newer".
- Como a cada nova execução dos testes são gerados novos diretórios com um timestamp diferente (ex.: "C:\Projects\VisualStudio\TestesComArquivos\TestResults\luciano.moreira_DSKSRN01 2009-10-26 14_26_18"), precisamos referenciar os arquivos dentro do diretório "Out", onde estão as DLLs do projeto.
- Como nossa propriedade em Configuração.RepositórioArquivos é somente leitura e não queremos interferir com a interface da classe, adicionarei um método internal chamado DefineRepositórioArquivos.
internal static void DefineRepositórioArquivos(string repositório) {
repositórioArquivos = repositório;
} - Para que esse método seja visível no nosso projeto de testes, utilizamos um pequeno recurso do .NET, definindo que os métodos internal do assembly de negócio são visíveis somente para o projeto de testes. Recurso que somente utilizo nesse tipo de cenário.
[assembly: InternalsVisibleTo("TestesComArquivos_TesteSuite")]
- A partir desse momento eu faço uma pequena alteração no setup do meu teste, para que ele defina qual o repositório de arquivos de acordo com o diretório de deployment do teste. Para isso eu utilizo a classe auxiliar TestContext, que possui a propriedade DeploymentDirectory. Se você não quiser usar essa classe auxiliar, pode partir para a ignorância com o AppDomain.CurrentDomain.BaseDirectory.
TestesComArquivos.Configuração.DefineRepositórioArquivos(TestContext.DeploymentDirectory);
Se você executar o seu teste nesse momento irá receber um erro! Analisando com cuidado verificará que o problema está no primeiro Assert, que pergunta pela existência do arquivo, então olhando o diretório criado pelos testes notará que o arquivo não foi colocado no Out. Huummm, mas no passo 1 você já pediu para o arquivo ser copiado para o diretório de saída, não é suficiente?
O pior é que não! Quando você compila o projeto de teste o arquivo é colocado no "\Bin\Debug" corretamente, mas não é levado para o "\TestResult\....\Out" que é criado para o teste. Para isso é necessário editar as configurações dos testes em "Local.testsettings" (dentro de Solution Items) e no Deployment adicionar o diretório "Arquivos", conforme figura abaixo.
Pronto!
Basta executar o seu teste que tudo vai funcionar e quantas vezes forem necessárias, pois cada novo teste copia o arquivo original para um novo diretório, evitando o primeiro problema que eu citei. Agora todos os seus desenvolvedores podem trabalhar tranquilamente, adicionar novos arquivos ao diretório já criado e codificar novos testes, basta lembrar de definir o diretório correto no início dos testes.
Bom, espero que tenham gostado. O projeto que criei está disponível juntamente com o PDF do artigo. Baixe aqui.
Luciano Caixeta Moreira - {Luti}
Chief Innovation Officer Sr. Nimbus Serviços em Tecnologia Ltda luciano.moreira@srnimbus.com.br
www.twitter.com/luticm


