Posts de November, 2009

[Rafael Biriba] Tunneling com Tsocks

Saturday, November 28th, 2009

network

Este post é um complemento de Tunneling: Passe por bloqueios de proxy ou de firewall com Socks

Porque usar Tsocks e não somente o socks ?

O Tsocks pode ser usado “por baixo” de qualquer programa e você não precisa ficar editando as configurações para informar o endereço de conexão socks. Permite também que você passe pelos bloqueios da rede, e assista videos do youtube por exemplo, coisa que não dá pra ser feito pelo tunneling convencional, devido conexão entre o player e o navegador cliente.

Tsocks redireciona todas as portas de comunicação para a sua conexão socks. Sendo assim, com ele você pode executar programas como mensageiros, navegadores e até jogos.

Lembrando que para utiliza-lo você precisa estabelecer uma conexão socks. Veja mais detalhes aqui.

Instalando o Tsocks:

(No ubuntu): sudo aptitude install tsocks
Ou pelo site http://tsocks.sourceforge.net/download.php

Configurando:

Apague todo conteudo do arquivo /etc/tsocks.conf e insira somente as seguintes linhas:
server = 127.0.0.1
server_type = 5
server_port = 8989

Onde server será sempre 127.0.0.1, máquina que roda o tsocks. Server_type refere-se a versão do socks, neste caso, usamos a versão 5. Server_port é o parâmetro mais importante. Ao estabelecer a conexão SSH, a porta informada deve ser a mesma que server_port.
(No exemplo:  ssh -D 8989 user@server.com)

Rodando:

Primeiro, certifique-se que o socks está estabelecido (Mais informações aqui). Feito isso, basta executar o comando no terminal:

tsocks firefox

OBS: Antes de executar o tsocks certifique-se que não há outro processo do firefox aberto. (Ou do programa que você pretende executar)

Faça uns teste em sites do tipo: meuip.com.br para verificar se está funcionando.Você pode executar o tsocks com qualquer programa.

Encerrando:

Basta fechar o programa que roda com o tsocks e fechar a conexão SSH (socks).

—-

Bom proveito ! :)



Leia também:

[Emerson Macedo] Law of Demeter simples em Ruby com a gem demeter

Thursday, November 26th, 2009

Depois de programar algum tempo em Ruby, me senti muito incomodado em ter que repetir um determinado código para manter minha estrutura respeitando a Law of Demeter. Pra quem não está familiarizado, segue um simples exemplo em Rails:


#models
class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

#view - erb|haml
@comment.post.title
@comment.post.name
@comment.post.something_else

O exemplo é um pouco forçado, mas o problema claro do exemplo é que estamos conhecendo demais sobre o objeto post dentro de comment. Se for necessário alguma alteração em algum dos atributos que estamos acessando diretamente, possivelmente isso resultará em modificações em cascata em todo código.

Depois dessa explicação básica para quem ainda não conhecia a Law of Demeter, vamos aplicar algumas soluções:

Segunda tentativa:


#models
class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
  def post_title
    post ? post.title : nil #preciso verificar se é nulo, caso contrário terei problemas
  end
  def post_name
    post ? post.name : nil #preciso verificar se é nulo, caso contrário terei problemas
  end
  def post_something_else
    post ? post.something_else : nil #preciso verificar se é nulo, caso contrário terei problemas
  end
end

#view - erb|haml
@comment.post_title
@comment.post_name
@comment.post_something_else

Essa mudança resolve o problema. Acontece que isso acaba sendo um pattern para resolver o problema, portanto, precisamos encontrar uma forma de não ficar repetindo esse código.

Quem já leu o livro The Pragmatic Programmer, tem bem na memória o capítulo que apresenta o conceito DRY – D’ont Repeat Yourself. Quem programa em Ruby e principalmente já usou o framework Rails sabe bem que DRY é um dos chavões que estão imbutidos na propaganda. Vamos então tentar fazer mais algumas modificações pra tentar alcançar esse objetivo:

Terceira tentativa:


#models
class Post < ActiveRecord::Base
  has_many :comments
end

require 'forwardable'
class Comment < ActiveRecord::Base
  extend Forwardable
  belongs_to :post
  def_delegator :post, :name, :post_name
  def_delegator :post, :title, :post_title
  def_delegator :post, :something_else, :post_something_else
end

#view - erb|haml
@comment.post_title
@comment.post_name
@comment.post_something_else

O módulo Forwardable já vem com o Ruby. Portanto, a solução mais obvia foi usar esse módulo para melhorar o exemplo anterior. Apesar de escrever menos código, essa alternativa tem o inconveniente de não verificar se o objeto post é nil, causando assim NoMethodError em alguns casos. Sendo assim, a alternativa anterior ainda parece ser mais adequada. Porém, a duplicação de código ainda me incomodava bastante, portanto, resolvi montar uma solução única que deu origem a gem demeter.

A solução definitiva:


#no shell
> sudo gem update --system
> sudo gem sources -a http://gemcutter.org
> sudo gem install demeter

#models
class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  extend Demeter     #extends demeter module
  demeter :post      #demeter post object
  belongs_to :post
end

#view
@comment.post_title
@comment.post_name
@comment.post_something_else

Basicamente o problema foi resolvido com 2 linhas de código:


  extend Demeter
  demeter :post

A vantagens são visíveis porque (1) você escreve bem menos, (2) já existe a verificação de objetos nulos e (3) caso você queira sobrescrever o comportamento padrão, basta criar um método que responda a mesma mensagem que a gem demeter responde. Dessa forma, o método criado pelo programador semrpe terá prioridade.

O código fonte do projeto está em http://github.com/emerleite/demeter com todas as instruções para utilização tanto em Ruby quanto em Ruby on Rails. O código fonte tem todos os testes automatizados que cobrem diversos cenários. O resultado desses testes podem ser vistos em http://runcoderun.com/emerleite/demeter. A página da gem fica em http://gemcutter.org/gems/demeter

Aguardo o feedback de vocês :)

[Tiago Motta] Utilizando asserts para testar layouts

Wednesday, November 25th, 2009

Um dos problemas encontrados em nossos testes de aceitação é a impossibilidade de validar a aparência exata do resultado final de uma determinada ação do usuário. Conseguimos validar com o watir se determinada div possui um texto, se determinado link está presente, mas nada impede que eles estejam escondidos, por trás de outro div, ou com letras da mesma cor do fundo. É sempre útil, mas não necessáriamente exato, sendo sempre um ponto de falha. Ainda mais em um sistema como o que estamos trabalhando em que o visual para o usuário tem uma grande importância.

Eu e o quixadá, mestre do javascript e meu par de hoje, trabalhamos em uma correção de bug visual, e como costumamos trabalhar com desenvolvimento outside-in, chegamos ao dilema de como criar um teste para garantir que a falha existia. A solução encontrada foi inserir asserts dentro do código javascript, tal qual a funcionalidade de asserts do java. O código da função assert ficou parecido com o mostrado abaixo:

function assert(mensagem,valorDesejado,valorRecebido) { if( valorDesejado != valorRecebido ) {   var html = '<div class="warning">' + mensagem + '</div>';   $('body').append(html);   throw mensagem; }}

Em nosso caso, tinhamos que ter a certeza de que após um clique do usuário a barra de rolagem do elemento mantinha-se da mesma forma que anteriormente. Então o código ficou parecido com o mostrado abaixo:

$.get( url, function ( responseHtml ) { var scrollAnterior = $('#opcoes').scrollTop(); substituiOpcoes( responseHtml ); assert( 'Deveria manter scroll igual', scrollAnterior, $('#opcoes').scrollTop() );});

No teste de aceitação verificamos então que o texto ‘Deveria manter scroll igual’ não deveria aparecer. O código do step do cucumber utilizando o watir pode ser visto abaixo:

Then /^a barra de rolagem deveria permanecer na mesma posição$/ do @browser.text.should_not include('Deveria manter scroll igual')end

Com o teste pronto e falhando, aí sim corrigimos a função javascript substituiOpcoes(html) de forma a manter o scroll anterior.

Não é uma solução perfeita. Estamos pesquisando uma melhor, como pode ser vista no post Testes de aceitação automáticos para Flash com T-Plan Robot do Anselmo. Mas enquanto isso podemos evitar alguns pontos de falha visuais que costumávamos ter que testar manualmente. Dado que nosso sistema possui 100% de cobertura de testes unitários, somados a 152 cenários de teste de aceitação que abragem 1568 passos, acho que estamos indo por um bom caminho.

[Tiago Peczenyj] Compatibilidade Binária em C

Thursday, November 19th, 2009

Programar em C é sempre divertido, principalmente se vc sabe o que faz. Um exemplo disso é como trabalhar com estruturas de dados complexas, ponteiros e casting.

Imaginem as duas estruturas abaixo:

typedef struct {
	int id;
	char name[128];
} tpessoa;
 
typedef struct {
	int id;
	char name[128];
	char rg[128];
} tpessoafisica;

Ok, tenho um tipo tpessoa e um tpessoafisica que representam um tipo básico (pessoa) e um tipo propositalmente extendido, especializado para algum fim (pessoa fisica). Posso ter um tipo para pessoa juridica, por exemplo.

Imagine que eu posso ter diversas operações com o tipo básico e, por acaso, quero utilizar também com o tipo extendido (tpessoafisica). Como fazer? Em algumas linguagens eu posso fazer isso:

tpessoafisica x = {...};
tpessoa y = (tpessoa) x;

Entretanto em C isso gera um erro de conversion to non-scalar type requested. Eu posso converter int para float, float para int, int para long, char para int, etc, mas conversão de estruturas não é bem por ai: até porque não existe uma clara noção do que deveria acontecer, certo?

Para isso temos que clamar pelo conceito de compatibilidade binária: Sendo duas estruturas de dados, A e B, se B especializa A de forma ter todos os mesmos atributos na ordem que foi definida em A (e, opcionalmente, alguma coisa a mais no final), eu posso fazer um cast de um ponteiro do tipo B para um ponteiro do tipo A.

Vejamos, o tpessoafisica tem no começo os mesmos atributos (id e name) que a tpessoa e, por acaso, tem um atributos rg a mais no final. Dessa forma eu posso fazer o cast dos ponteiros na ordem apropriada.

void mostra_pessoa(tpessoa *x){
	printf("Pessoa { id = %d, name = %s }\n",x->id,x->name);
}
 
int main(){
	tpessoafisica x = {100, "pacman", "666"};
	// cast vale para ponteiros, por isso uso o operador &
	mostra_pessoa((tpessoa *) &x);
	return 0;
}

Ou seja, mostra pessoa esta preparado para receber um ponteiro do tipo tpessoa mas, graças a um habil cast de ponteiros aproveitando o principio de compatibilidade binária eu posso passar o endereço de uma estrutura diferente, no caso de tpessoafisica.

Perceba que eu preciso de um cast entre ponteiros, por isso eu preciso apelar para um & na frente da variavel, pegando o endereço de memória associado aquela variavel. Este recurso é util em muitas situações, desde simular interfaces e herança até coisas mais divertidas como fazer perl 5.x rodar perl 6.

[Tiago Peczenyj] Compatibilidade Binária em C

Thursday, November 19th, 2009

Programar em C é sempre divertido, principalmente se vc sabe o que faz. Um exemplo disso é como trabalhar com estruturas de dados complexas, ponteiros e casting.

Imaginem as duas estruturas abaixo:

typedef struct {
	int id;
	char name[128];
} tpessoa;
 
typedef struct {
	int id;
	char name[128];
	char rg[128];
} tpessoafisica;

Ok, tenho um tipo tpessoa e um tpessoafisica que representam um tipo básico (pessoa) e um tipo propositalmente extendido, especializado para algum fim (pessoa fisica). Posso ter um tipo para pessoa juridica, por exemplo.

Imagine que eu posso ter diversas operações com o tipo básico e, por acaso, quero utilizar também com o tipo extendido (tpessoafisica). Como fazer? Em algumas linguagens eu posso fazer isso:

tpessoafisica x = {...};
tpessoa y = (tpessoa) x;

Entretanto em C isso gera um erro de conversion to non-scalar type requested. Eu posso converter int para float, float para int, int para long, char para int, etc, mas conversão de estruturas não é bem por ai: até porque não existe uma clara noção do que deveria acontecer, certo?

Para isso temos que clamar pelo conceito de compatibilidade binária: Sendo duas estruturas de dados, A e B, se B especializa A de forma ter todos os mesmos atributos na ordem que foi definida em A (e, opcionalmente, alguma coisa a mais no final), eu posso fazer um cast de um ponteiro do tipo B para um ponteiro do tipo A.

Vejamos, o tpessoafisica tem no começo os mesmos atributos (id e name) que a tpessoa e, por acaso, tem um atributos rg a mais no final. Dessa forma eu posso fazer o cast dos ponteiros na ordem apropriada.

void mostra_pessoa(tpessoa *x){
	printf("Pessoa { id = %d, name = %s }\n",x->id,x->name);
}
 
int main(){
	tpessoafisica x = {100, "pacman", "666"};
	// cast vale para ponteiros, por isso uso o operador &
	mostra_pessoa((tpessoa *) &x);
	return 0;
}

Ou seja, mostra pessoa esta preparado para receber um ponteiro do tipo tpessoa mas, graças a um habil cast de ponteiros aproveitando o principio de compatibilidade binária eu posso passar o endereço de uma estrutura diferente, no caso de tpessoafisica.

Perceba que eu preciso de um cast entre ponteiros, por isso eu preciso apelar para um & na frente da variavel, pegando o endereço de memória associado aquela variavel. Este recurso é util em muitas situações, desde simular interfaces e herança até coisas mais divertidas como fazer perl 5.x rodar perl 6.

[Rafael Biriba] Melhor Prevenir do que Remediar: Backup do Blog

Tuesday, November 17th, 2009
www.rafaelbiriba.com

http://www.rafaelbiriba.com/

No início dessa semana o servidor do blog teve um pequeno problema de energia, alguma coisa queimou no datacenter e o blog ficou 12 horas fora do ar !

Esse post (pelo menos agora com o mesmo titulo) já havia sido publicado na noite do dia 10 de novembro. Na manhã do dia 11, esse mesmo servidor teve problemas em alguns disco da RAID e até o sistema operacional teve que ter sido reinstalado. Para completar a história trágica, um backup do dia 7 de novembro restaurou todos os dados do blog, depois de dias fora do ar.

blog-audience-downtimeA empresa responsável pelo servidor perguntou se eu tinha algum backup mais atual dos meu dados,…, eu só tinha um do mês anterior, então fiquei quietinho e aceitei o backup deles… (E logicamente ganhei um bom desconto na mensalidade, devido as danos…)

Só pra finalizar e esquecer essa trágica semana, o problema foi resolvido depois de 5 dias fora do ar… Como mostra o gráfico das estatísticas de acesso, onde agora tenho um “buraco” por falta de acesso… :(

O intervalo entre postar essa matéria e meu blog ter saído do ar foi tão próxima, que o google nem indexou o conteúdo, e nem deu tempo de gerar um backup do blog. Então tenho que reescrever o post…

Bom, para você não passar por essa situação chata e constrangedora que eu passei, você precisa fazer o backup do banco de dados e dos arquivos (principalmente as imagens) do seu blog.

Vamos por parte:

Backup do Banco de Dados

WP-DB-Backup: http://wordpress.org/extend/plugins/wp-db-backup/

Faz o backup do banco, comprime e envia por email. É possível fazer isso tanto manualmente, quanto automaticamente. Você pode configurar para fazer isso a cada 5 min, a cada hora, uma vez por dia, e etc… Recebendo tudo no seu email, tendo uma cópia fiél do BD do seu blog. (Inclusive comentário, rascunhos, configurações de plugins e etc..)

Backup do Arquivos

Wordpress Backup: http://wordpress.org/extend/plugins/wordpress-backup/

Esse plugin completou o pacote de ferramentas… Ele faz o backup das pasta de plugins, temas e uploads (onde tem as fotos e etc…. )
Porém, um de suas funcionalidades deve ser usada com cuidado. Ele tem uma opção de enviar esses pacotes .zip para um email. Não faça isso. Com certeza seu PHP não tem alocação de memória suficiente para isso, e fará com que seu blog saia do ar (Testei e foi o que aconteceu.). O autor diz a mesma coisa na descrição do plugin: Be sure that your memory limits are set high enough in your php.ini

Então, para que serve o plugin ? Simples, ele cria o .zip dos seu diretórios e disponibiliza em uma pasta para download. Com isso você pode criar um script para fazer o download dos arquivos periodicamente. Exemplo prático: (Eu fiz para mim algo mais elaborado, mas esse aqui já é um começo)

wget http://www.seublog.com/wp-content/bte-wb/plugins.zip && mv plugins.zip backup/ || rm plugins.zip
wget http://www.seublog.m/wp-content/bte-wb/themes.zip && mv themes.zip backup/ || rm themes.zip
wget http://www.seublog.com/wp-content/bte-wb/uploads.zip && mv uploads.zip backup/ || rm uploads.zip

Explicando… Ele tenta baixar os três arquivos que o plugin gera. Caso consiga baixar o pacote com sucesso, ele move para uma pasta chamada backup, ou se houver alguma falha durante o download, ele deleta o arquivo corrompido.

Dica para o plugin: Troque a pasta padrão bte-wb. Se você não trocar o nome dessa pasta, qualquer um pode ter acesso a seus arquivos, principalmente o uploads.zip. Renomeie a pasta para algo mais difícil de alguém descobrir…

Então seja esperto e fique de olho. Nunca se sabe quando você vai precisar de um backup. Então é bom sempre ter um em mãos…


Leia também:

[Bruno Mentges de Carvalho] Git – como usar tags

Friday, November 13th, 2009

Alguns comandos para usar tags com git:

  • Listar tags: git tag
  • Criar uma tag do branch local: git tag minha-tag
  • Fazer push das tags: git push –tags origin master (tem dois sinais de menos ao lado do tags ;)
  • Renomear uma tag: git tag -m minha-tag minha-nova-tag
  • Deletar uma tag local: git tag -d minha-tag
  • Deletar uma tag remota, no origin: git push origin :refs/tags/minha-tag

[Bruno Mentges de Carvalho] Git – como usar tags

Friday, November 13th, 2009

Alguns comandos para usar tags com git:

  • Listar tags: git tag
  • Criar uma tag do branch local: git tag minha-tag
  • Fazer push das tags: git push –tags origin master
  • Renomear uma tag: git tag -m minha-tag minha-nova-tag
  • Deletar uma tag local: git tag -d minha-tag
  • Deletar uma tag remota, no origin: git push origin :refs/tags/minha-tag

[Evandro Flores] Feira de ciências – o melhor review

Friday, November 13th, 2009

A alguns Sprints, estávamos percebendo que nosso Review não estava atendendo a seu princípio básico que é pegar feedback sobre o que foi desenvolvido, nós estávamos ao contrário apresentando as histórias em um projetor, com POs, SMs, Time e clientes sentados ouvindo o que estava sendo dito por um ou dois membros do time, na maioria das vezes os ouvintes sequer se pronunciavam durante a apresentação, mesmo eventualmente tendo sugestões ou até percebendo alguma coisa errada.

Foi quando o Danilo (e o Igor) deu deram uma excelente idéía, que aproximou o cliente (e todos os interessados) das histórias que estavam sendo entregues nesse Sprint.

A idéia da dinâmica surgiu a partir do livro Agile Project Management with Scrum do Ken Schwaber (Sprint Review Meeting: páginas 56-57), e é realmente similar a uma feira de ciências, aonde cada um mostra o que fez e explica seu projeto bem de perto.

Em uma sala grande, colocamos cinco mesas com computadores, papel, caneta e é claro post-its. Os membros do time foram distribuídos nas mesas e apresentavam as histórias a quem estivesse naquela “bancada”, os participantes poderiam livremente navegar no computador para utilizar a solução, eventualmente tirar dúvidas e a partir daí escrever nos post-its sugestões de melhorias a serem avaliadas pelo PO posteriormente.

A proximidade das pessoas durante o review trouxe um clima muito mais colaborativo do que tinhamos nas apresentações, realmente surgiram melhorias, não só nas histórias mas também no processo, identificamos alguns pontos, discutimos na retrospectiva e conseguimos aplicar no sprint seguinte.

[Evandro Flores] Feira de ciências – o melhor review

Friday, November 13th, 2009

A alguns Sprints, estávamos percebendo que nosso Review não estava atendendo a seu princípio básico que é pegar feedback sobre o que foi desenvolvido, nós estávamos ao contrário apresentando as histórias em um projetor, com POs, SMs, Time e clientes sentados ouvindo o que estava sendo dito por um ou dois membros do time, na maioria das vezes os ouvintes sequer se pronunciavam durante a apresentação, mesmo eventualmente tendo sugestões ou até percebendo alguma coisa errada.

Foi quando o Danilo deu uma excelente idéía, que aproximou o cliente (e todos os interessados) das histórias que estavam sendo entregues nesse Sprint.

A idéia da dinâmica surgiu a partir do livro Agile Project Management with Scrum do Ken Schwaber (Sprint Review Meeting: páginas 56-57), e é realmente similar a uma feira de ciências, aonde cada um mostra o que fez e explica seu projeto bem de perto.

Em uma sala grande, colocamos cinco mesas com computadores, papel, caneta e é claro post-its. Os membros do time foram distribuídos nas mesas e apresentavam as histórias a quem estivesse naquela “bancada”, os participantes poderiam livremente navegar no computador para utilizar a solução, eventualmente tirar dúvidas e a partir daí escrever nos post-its sugestões de melhorias a serem avaliadas pelo PO posteriormente.

A proximidade das pessoas durante o review trouxe um clima muito mais colaborativo do que tinhamos nas apresentações, realmente surgiram melhorias, não só nas histórias mas também no processo, identificamos alguns pontos, discutimos na retrospectiva e conseguimos aplicar no sprint seguinte.