Performance testing can be a tricky proposition, how many times have you deployed code that fell apart in production? (Hey, we've all done it!) Having a staging environment, which replicates the data and deployment environments are great first steps, but even that often falls short from producing reliable results. And that is where load testing comes in: we need to test our application in the context of a multi-user audience interacting with all of the components of our site. Great, but how do we do that? Well, why not just grab the access logs from your current production environment, and replay them!
If you start looking, you'll find an abundance of benchmarking applications, but the commonly cited industry standards are: Apache Bench, JMeter, httperf, and Siege.
Apache Bench (or 'ab', on the command line) is usually the crowd favorite as it is ubiquitous due to being packaged alongside the Apache web-server - and for a good reason, it's a great benchmarking tool. However, while it can generate a significant concurrency load, the requests are always identical (Siege also has this limitation), as it has no mechanism for simulating a collection of user sessions:
# make 100 requests, opening 20 concurrent requests at a time
igvita@igvita.com [~]# ab -n 100 -c 20 http://localhost/
...snip...
Concurrency Level: 20
Time taken for tests: 0.78639 seconds
Complete requests: 100
Benchmarking a single endpoint is an important use case, but oftentimes we should really be testing an entire transaction: a series of user-initiated requests simulating a common use case of your web application (searching for, and purchasing an item; updating a profile; etc.). In the load testing world, this is also commonly known as simulating a session.

JMeter is the tool that you're looking for if you need to create a series of highly customizable interactions. While the UI of JMeter can be definitely confusing at first, a good guide and some experimentation will allow you to create custom scripted sessions with cookies, login and logout actions, and anything else your heart might desire.
But while JMeter is nice, it's definitely a heavy-weight, and that's where httperf comes into the picture (http_load is also a great app, albeit without many of the features of httperf). Unlike JMeter, httperf is powered from the command line and offers a much simpler (but feature rich) path for simulating a collection of users.
Httperf under the hoodCreated at the HP Research Labs (see original paper), and more recently updated by researchers at University of Calgary, httperf packs a lot of functionality under the hood: url generation, burst support, think times, GET/POST queries in the session file, and different concurrency rates amongst many others.
To get started with httperf, check out Sofia Cardita's great introductory guide, as well as the slides and the quickstart guide from Theodore Bullock's presentation at WWW2007.
AutoPerf: Ruby httperf driverFinally, putting all of the pieces of the puzzle together, how do we run a simple, log-replay load test for a Rails application? First, we need a log file, let's say from Nginx, and then we need to convert it into a format httperf can understand:
# Grab the last 1000 requests from production Nginx log, and extract the request path (ex: /index)
tail -n 1000 nginx.log | awk '{print $7}' > requests.log
# Replace newlines with null terminator (httperf format)
tr "\n" "\0" < requests.log > requests_httperf.log
# Run an httperf test, using our replay log
# - test localhost deployment
# - simulate 100 concurrent users
# - stop after 10000 requests have been made
httperf --hog --server localhost --port 80 --wlog=n,requests_httperf.log --rate=100
Running one of these tests will provide you with a mountain of data, but how do you map the performance curve as request rate changes? Do you know at which point your server becomes saturated? To help with this task, I've created autoperf.rb, a small Ruby driver for httperf. Let's create a simple execution plan for it:
> autoperf.conf
# Autoperf Configuration File # The host and port to test. host = localhost port = 80 # The 'rate' is the number of number of connections to open per second. # A series of tests will be conducted, starting at low rate, # increasing by rate step, and finishing at high_rate. low_rate = 100 high_rate = 200 rate_step = 20 ################# # httperf options (prefix with 'httperf_') httperf_wlog = n,requests_httperf.log # num_conn is the total number of connections to make during a test # num_call is the number of requests per connection # The product of num_call and rate is the the approximate number of # requests per second that will be attempted. #httperf_num-conns = 20 httperf_num-call = 1 # timeout sets the maximimum time (in seconds) that httperf will wait # for replies from the web server. If the timeout is exceeded, the # reply concerned is counted as an error. httperf_timeout = 5Downloads: 2 File Size: 0.0 KB
With that in place, we're ready to go:
> autoperf.out
> ruby autoperf.rb -c autoperf.conf ... +----------------------------------------------------------------+ | rate | conn/s | req/s | replies/s avg | errors | net io (KB/s) | +----------------------------------------------------------------+ | 100 | 99.9 | 99.9 | 99.7 | 0 | 45.4 | | 120 | 119.7 | 119.7 | 120.0 | 0 | 54.4 | | 140 | 139.3 | 139.3 | 138.0 | 0 | 63.6 | |> 160 | 151.9 | 151.9 | 147.0 | 0 | 69.3 | | 180 | 132.2 | 129.8 | 137.4 | 27 | 59.6 | | 200 | 119.8 | 117.6 | 139.9 | 31 | 53.9 | +----------------------------------------------------------------+As you can see, the server became saturated at about 160 req/s based on the access patterns generated in our production environment - a far better benchmark than testing a single endpoint. Best of all, now you can map your performance benchmarks to real user sessions in an automated and repeatable fashion. No more falling down in production!
Hi Cluster Fans,
Resources can be hard to find, so every few months we will be publishing an updated list of useful documents, guides and information to this blog (http://blogs.msdn.com/clustering/).
If there is any other useful Microsoft content which you feel is missing, let us know by clicking the 'email' link in the upper right corner of the page and send us the resource and URL.
Thanks,
Symon Perriman
Program Manager
Clustering & HA
Microsoft
Useful Sources
· Blog: Cluster Team: http://blogs.msdn.com/clustering/
· Blog: Ask Core: Clustering
· Training: Course 6423a: Implementing and Managing WS08 Clustering
· Website: Cluster Technical Resources
· Website: Cluster Information Portal
· Website: Clustering Forum (2008)
· Website: Clustering Forum (2008 R2)
· Website: Clustering Newsgroup
Windows Server 2008 R2
· Blog Guide: Deploying Cluster Shared Volumes (CSV)
· Blog Guide: Cluster Shared Volumes (CSV): Disk Ownership
· Blog Guide: PowerShell for Network Load Balancing (NLB) in Windows Server 2008 R2
· Blog Guide: PowerShell for Failover Clustering in Windows Server 2008 R2
· Blog Guide: Live Migration Traffic
· Blog Guide: How to manually defrag or ChkDisk a CSV disk
· TechNet Guide: Using Live Migration in Windows Server 2008 R2
· TechNet Guide: What??s new in R2 Clustering
· Webcast: Innovating High Availability with Cluster Shared Volumes (CSV)
· Webcast: Failover Clustering Feature Roadmap in WS08 R2
· Whitepaper: Windows Server 2008 R2 & Microsoft Hyper-V Server 2008 R2 - Hyper-V Live Migration Overview & Architecture
· Webcast: Windows Server 2008 R2 Live Migration
· Webcast: Clustering in a Virtual World
· Website: Clustering Forum (2008 R2)
Architecture
· Blog Guide: Cluster Virtual Adapter (NetFT)
· Blog Guide: PlumbAllCrossSubnetRoutes
· Whitepaper: Failover Cluster Architecture Overview
Core
· Guide: Server Core
· TechNet: Installation
· Utility: Remote Server Administration Tools (simplifies Server Core configurations)
· Webcast: How Microsoft does IT: Enhancing High Availability with Server Core in Windows Server 2008
Deployment / Migration / Upgrade
· Blog Guide: Migration Options for Hardware
· Blog Guide: PrintBRM Error 0x80070043 workaround
· Blog Guide: DHCP Database migration to Windows Server 2008
· Blog Guide: PrintBRM.exe, 0?80070043 and Print Clusters - A Workaround
· KB Guide: Exchange 2003: Move Mailbox
· KB Article: SQL Server 2008 Rolling Upgrades
· KB Article: Cluster Nodes as Domain Controllers (DCs)
· MSDN Guide: SQL Upgrade Paths
· MSDN Guide: SQL Cluster Upgrade
· TechNet Guide: Migrating Cluster Settings
· TechNet Guide: Failover Clustering Deployment
· TechNet Guide: Validating Hardware for a Failover Cluster
· TechNet Guide: Installing a Failover Cluster
· TechNet Guide: Creating a Failover Cluster
· TechNet Guide: Cluster Requirements
· TechNet Guide: Validating a cluster
o Blog Guide: Validation Warning: Teredo
o Blog Guide: Validation Warning: Patch GUID
· TechNet Guide: Configuring Accounts in Active Directory
· TechNet Guide: Recommended Clustering Hotfixes (2003)
· TechNet Guide: Recommended Clustering Hotfixes (2003 SP2)
· TechNet Guide: Recommended Clustering Hotfixes (2008)
· TechNet Guide: Exchange 2007 Overview
· TechNet Guide: Exchange 2007 Cmdlets
· TechNet Guide: Print Migration Overview
· TechNet Guide: UI: Print Migration Tool/Wizard
· Utility: File Server Migration Toolkit (FSMT) (2008)
Exchange Server
· Lab: TechNet Virtual Lab: Exchange Server 2007 Standby Continuous Replication
· Lab: TechNet Virtual Lab: Using Cluster Continuous Replication (CCR) in Exchange 2007
· TechNet: Installing Cluster Continuous Replication (CCR) on 2008
· TechNet: Deploying Exchange 2003 in a Cluster
· TechNet: Planning for Cluster Continuous Replication (CCR)
· TechNet: Installing CCR on Windows Server 2008
· TechNet: How to create an Exchange SCC Failover Cluster with CMD
· Webcast: How Microsoft IT Implemented New Storage Designs for Exchange Server 2007
· Webcast: Exchange 2007 High Availability Deep Dive
File Server
· Blog Guide: File Share ??Scoping?? in Windows Server 2008 Failover Clusters
· Blog Guide: Share Subdirectories in Windows Server 2008
· TechNet Guide: Configuring a Two-Node File Server Failover Cluster
· TechNet Guide: Creating a Clustered File Server checklist
· TechNet Guide: Create a Shared Folder in a Clustered File Server
· WebCast: TechNet Webcast: Prepare Yourself for Windows Server 2008 (Part 5 of 8): New File Server Features
· WebCast: How Microsoft IT Deploys Windows 2008 Clusters for File Services
· Webcast: New File Server Features of Windows Server 2008 (Level 200)
· Blog Guide: Deploying a HA Virtual Machine (2008)
· Blog Guide: HA Virtual Machine Deployment Considerations (2008)
· Blog Guide: Network Load Balancing (NLB) and Virtual Machines
· Blog Guide: Adding a Pass-Through Disk to a HA VM
· Blog Guide: SCVMM: Intelligent Placement
· Blog Guide: Monitor Network Traffic for a VM on a Cluster
· TechNet Case Study: How Microsoft IT Designs the Virtualization Host & Network Infrastructure
· TechNet Case Study: Best Practices for Deploying VMs using Hyper-V
· TechNet Guide: Getting Started with Hyper-V
· TechNet Guide: High-Availability for a Server Running Hyper-V
· TechNet Guide: Design for a Failover Cluster in Which All Nodes Run Hyper-V
· TechNet Guide: Requirements and Recommendations for Failover Clusters in Which All Nodes Run Hyper-V
· TechNet Guide: Failover Cluster in which the Servers run Hyper-V
· TechNet Webcast: 24 Hours of Windows Server 2008 (Part 24 of 24): High Availability with Hyper-V
· TechNet Webcast: Creating Business Continuity Solutions Using Windows Virtualization
· TechNet Webcast: High Availability with Hyper-V
· Webcast: Top 10 VMWare Myths, including CSV and live migration
· Webcast: Hyper-V Quick Migration on a Failover Cluster
· Whitepaper: Quick Migration with Hyper-V
· Whitepaper: Testing Hyper-V and Failover Clustering
Miscellaneous Resources
· Blog Guide: Add a New Disk to a Cluster (2008)
· Blog Guide: Configuring Auditing for a Cluster (2008)
· Blog Guide: Cluster Recovery (2003)
· KB Article: The Microsoft Support Policy for Windows Server 2008 Failover Clusters
· TechNet Guide: Configuring the Quorum in a Failover Cluster
· TechNet Guide: Managing a Failover Cluster
· TechNet Guide: Modifying Settings for a Failover Cluster
· TechNet Guide: The Failover Cluster Management Snap-In
· TechNet Guide: Understanding Backup and Recovery Basics for a Failover Cluster
· TechNet Guide: Support Policy
· TechNet Guide: Windows Server 2008 Itanium / IA64 support
· Webcast: Top 10 Windows Server 2008 Failover Clustering Enhancements over Windows Server 2003 Clustering, Based on Best Practices (Level 300)
· Webcast: Failover Clustering 101
· Webcast: Achieving High Availability with Windows Server ??Longhorn? Clustering (Level 200)
· Whitepaper: Microsoft??s HA Strategy
· Whitepaper: Overview of Failover Clustering
· Whitepaper: HA with Microsoft MPIO (2003, 2008)
· Website: Windows Logo site
· Webcast: Introduction to Failover Clustering
Multi-Site Clustering· Cluster Team Site: http://www.microsoft.com/windowsserver2008/en/us/failover-clustering-multisite.aspx
· KB Article: Deployment Considerations for Windows Server 2008 failover cluster nodes on different, routed subnets
· Webcast: TechNet Webcast: Geographically Dispersed Failover Clustering in Windows Server 2008 Enterprise
· Webcast: How You Can Achieve Greater Availability with Failover Clustering Across Multiple Sites (Level 300)
· Whitepaper: Multi-site Clustering
· Webcast: Multi-Site Clustering in Windows Server 2008
Network Load Balancing
· Blog Guide: Network Load Balancing (NLB) and Virtual Machines
· KB Article: NLB Troubleshooting Overview
· KB Article: Create/manage/destroy NLB clusters via NLB Manager remotely from another server, or from RSAT client (admin pack) on Vista
· Presentation: Server Core: Install the NLB feature
· TechNet Guide: Configuring NLB with Terminal Services
· TechNet Guide: NLB Deployment Guide
· TechNet Guide: Implementing a new NLB Cluster
· TechNet Guide: Verifying the NLB Cluster and Enabling Client Access
· TechNet Guide: Overview of NLB
· TechNet Guide: Creating NLB Clusters
· TechNet Guide: Managing NLB Clusters
· TechNet Guide: Setting NLB Parameters
· TechNet Guide: Controlling Hosts on NLB clusters
· TechNet Guide: Troubleshooting for System Event Messages Related to NLB Cluster
· TechNet Guide: User Interface: NLB Manager
· TechNet Guide: Upgrading a NLB Cluster
· TechNet Guide: Upgrading a Network Load Balancing (NLB) Cluster
· Webcast: 24 Hours of Windows Server 2008 (Part 23 of 24): Failover Clustering and Network Load Balancing z
Other Resources / Workloads
· Blog Guide: Configure Multiple Instances of MSDTC (2008)
· Blog Guide: Installing MSDTC (2003)
· Blog Guide: Optimize Print Cluster (2003)
· Blog Guide: Creating and Configuring a Generic Application Resource
· TechNet Guide: Configuring Generic Resources
· TechNet Guide: Configure a Service or Application for High Availability
Scripting
· Blog Guide: Creating a Cluster using WMI
· Blog Guide: CLI: Cluster Resource Groups
· Blog Guide: CLI: Quorum
· Blog Guide: CLI: Disk Resources
·</fo
[clustering nlb cluster failover wsfc network load balancing windows server 2008 core exchange symon perriman SQL hyper-v file server r2 windows server 2008 r2 deployment multi-site scripting ]
Clustering and High Availability : Microsoft Blog - Microsoft server and infrastructure technology blogs, news and resources
View original post
|Add to del.icio.us| Created more than one year ago
| Share
| ?Older revision | Revision as of 17:52, 19 February 2009 | ||
| Line 9: | Line 9: | ||
| ; [http://www.openprinting.org/download/printdriver/macosx/min12xxw-0.0.92-ub.dmg min12xxw-0.0.92-ub.dmg] (125KB) | ; [http://www.openprinting.org/download/printdriver/macosx/min12xxw-0.0.92-ub.dmg min12xxw-0.0.92-ub.dmg] (125KB) | ||
| : The min12xxw package requires, but does not include, Foomatic-RIP or GPL Ghostscript for Mac OS X. '''Download these items from the links below, if necessary.'''<br />[http://www.hinterbergen.de/mala/min12xxw/min12xxw-0.0.9.tar.gz source code] | : The min12xxw package requires, but does not include, Foomatic-RIP or GPL Ghostscript for Mac OS X. '''Download these items from the links below, if necessary.'''<br />[http://www.hinterbergen.de/mala/min12xxw/min12xxw-0.0.9.tar.gz source code] | ||
| - | ; [http://www.openprinting.org/download/printdriver/macosx/foomatic-rip-2008-01-30.dmg Foomatic-RIP] (224KB) | + | <h3>Foomatic-RIP for Mac OS X 10.5.x (Leopard), Mac OS X 10.4.x (Tiger), and Mac OS X 10.3.x (Panther)</h3> |
| - | : The Foomatic-RIP package installs the necessary core runtime components (the foomatic-RIP CUPS filter and the foomatic-gswrapper) to enable printing with Foomatic machinery in Mac OS X. '''Foomatic-RIP is required for all users. It is not necessary to install Foomatic-RIP more than once.'''<br />source code included on disk image | + | ; [http://www.openprinting.org/download/printdriver/macosx/foomatic-rip-4.0.0.203-ub.dmg Foomatic-RIP] (2.2 MB) |
| + | : The Foomatic-RIP package installs the necessary core runtime components to enable printing with Foomatic machinery in Mac OS X. This package is generally not useful without Ghostscript and at least one foomatic PPD. Please see the [[#Usage|usage]] instructions below for more details. <b>MOST USERS WILL NEED TO UPGRADE THEIR VERSION OF GHOSTSCRIPT</b> to the most recent version (the version listed below).<br />source code included on disk image | ||
| + | |||
| <h3>Ghostscript for Mac OS X 10.5.x (Leopard), Mac OS X 10.4.x (Tiger), and Mac OS X 10.3.x (Panther)</h3> | <h3>Ghostscript for Mac OS X 10.5.x (Leopard), Mac OS X 10.4.x (Tiger), and Mac OS X 10.3.x (Panther)</h3> | ||
| ; [http://www.openprinting.org/download/printdriver/macosx/gplgs-8.64so-ub.dmg gplgs-8.64so-ub.dmg] (32.5 MB) | ; [http://www.openprinting.org/download/printdriver/macosx/gplgs-8.64so-ub.dmg gplgs-8.64so-ub.dmg] (32.5 MB) | ||
| - | : GPL Ghostscript 8.64 is an open-source PostScript interpreter that includes integrated support for the CUPS printing system in Mac OS X. It is the replacement for ESP Ghostscript.<br /><b>GPL Ghostscript is required for all users. It is not necessary to install Ghostsccript more than once.</b><br /> [http://ghostscript.com/releases/ghostscript-8.64.tar.gz source code] | + | : GPL Ghostscript 8.64 is an open-source PostScript interpreter that includes integrated support for the CUPS printing system in Mac OS X. It is the replacement for ESP Ghostscript.<br /><b> GPL Ghostscript is required for all users.</b><br /> [http://ghostscript.com/releases/ghostscript-8.64.tar.gz source code] |
| + | <p><br /></p> | ||
| + | <hr /> | ||
| + | <h3>Foomatic-RIP for Mac OS X 10.2.x (Jaguar)</h3> | ||
| + | ; [http://www.openprinting.org/download/printdriver/macosx/foomatic-rip-2008-01-30.dmg Foomatic-RIP] (224KB) | ||
| + | : <nowiki> The Foomatic-RIP package installs the necessary core runtime components (the foomatic-RIP CUPS filter and the foomatic-gswrapper) to enable printing with Foomatic machinery in Mac OS X. This package is generally not useful without Ghostscript and at least one foomatic PPD. Please see the</nowiki> [[#Usage|usage]] <nowiki>instructions below for more details. </nowiki><br />source code included on disk image | ||
| <h3>Ghostscript for Mac OS X 10.2.x (Jaguar)</h3> | <h3>Ghostscript for Mac OS X 10.2.x (Jaguar)</h3> | ||
| ; [http://www.openprinting.org/download/printdriver/macosx/gplgs-8.61-jaguar-ppc.dmg gplgs-8.61-jaguar-ppc.dmg] (17.1 MB) | ; [http://www.openprinting.org/download/printdriver/macosx/gplgs-8.61-jaguar-ppc.dmg gplgs-8.61-jaguar-ppc.dmg] (17.1 MB) | ||
| : GPL Ghostscript 8.61 is an open-source PostScript interpreter that includes integrated support for the CUPS printing system in Mac OS X. It is the replacement for ESP Ghostscript. <br /><b>GPL Ghostscript is required for all users. It is not necessary to install Ghostsccript more than once.</b><br /> [http://downloads.sourceforge.net/ghostscript/ghostscript-8.61.tar.gz?download source code] | : GPL Ghostscript 8.61 is an open-source PostScript interpreter that includes integrated support for the CUPS printing system in Mac OS X. It is the replacement for ESP Ghostscript. <br /><b>GPL Ghostscript is required for all users. It is not necessary to install Ghostsccript more than once.</b><br /> [http://downloads.sourceforge.net/ghostscript/ghostscript-8.61.tar.gz?download source code] | ||
| - | |||
| '''Please note:''' all packages require Mac OS X version 10.2 or newer. | '''Please note:''' all packages require Mac OS X version 10.2 or newer. | ||
| - | |||
| </div> | </div> | ||
| <p> | <p> |
Sinceramente espero que no, pero a veces la fe me flaquea ;-)

Os contaré una pequeña historia, y saldré un poco del armario en el proceso: antes de trabajar en serio con Rails y Ruby, nunca jamás había desarrollado con tests, y ni siquiera tenía muy claro cuáles podían ser las ventajas de hacerlo, ni cómo funcionaba el asunto. Fue la exposición a la (nunca suficientemente alabada) comunidad rubista y railera la que me hizo llegar a donde estoy hoy y llevo ya algún tiempo: a pensar que el testing es La Manera Correcta De Hacer Las Cosas™ (con toda la cautela e ironía que siempre lleva esa frase saliendo de mi boca). Quiero decir que todo lo que sé y opino acerca de testing, TDD, BDD, etc., es lo que he aprendido en estos casi cuatro años; no es poco, pero tampoco puede decirse que sea una visión muy general ni universal. Vaya eso por delante.
Durante este tiempo, mi arsenal de herramientas y técnicas ha ido creciendo y cambiando: Test::Unit, Shoulda, mocking, RSpec, integración contínua, tests de integración y aceptación, Cucumber, Selenium. El patrón de adopción era siempre similar: algo que te hacía perder un poco de productividad y velocidad de desarrollo, a cambio de mejorar la calidad de tu código, su mantenibilidad y en general su capacidad para no darte problemas en el futuro. De alguna forma, era el proceso contrario a la contracción de deuda técnica: comprabas productividad a medio y largo plazo pagándola con productividad a corto plazo. Suponiendo que el mundo no se acabe mañana, parece una buena idea, funcionaba y todo el mundo era feliz. Expresabas tus fuertes opiniones a los cuatro vientos, eras respetado por tu compromiso con el código de calidad, te ofrecían trabajar en proyectos la hostia de chulos, dabas conferencias, y ponías la palabra TESTING así en mayúsculas y a todo lo que da en pantallas de 4 metros.
Mientras tanto, en otro rincón de la galaxia (que sin embargo era básicamente el mismo), un grupo de entusiastas rubistas de Madrid andaba montando periódicamente Monsters of Ruby (también conocido en una de sus encarnaciones como Rails Hackathon). En el más reciente (semana pasada), la idea era poner a varios equipos a contruir en paralelo la misma aplicación, en Rails, al objeto de compartir conocimiento, contrastar enfoques, y ya de paso echarnos unas risas compitiendo. Dado que la mayoría de los participantes están acostumbrados a usar tests, se nos ocurrió que una buena manera de especificar a los equipos cuál era su cometido era entregar un conjunto de tests que la aplicación tenía que acabar pasando. Aceptación en estado puro. Con el entusiasmo del que cree en lo que hace, montamos un conjunto de pruebas para entregar a los equipos, con lo más chipén, state-of-the-art, lo que hay que hacer ahora para impresionar a las nenas y en definitiva lo que podéis escuchar en cualquier conversación en cualquier bar del país: RSpec, Cucumber, Webrat y Selenium. Como dice Dani, lo único que importa es molar.
EPIC FAIL

Ni uno sólo de los equipos completó, digamos, el 25% de la aplicación. ¿En qué momento de la historia que acabo de contar se torció todo? Parecía buena idea, éramos jóvenes y entusiastas y volveríamos a hacerlo. Todos y cada uno de los cambios de herramientas de los que he hablado fueron meditados, valorados en términos de trade-off y aceptados porque compensaban. El problema es que todos esos cambios eran paulatinos y apenas perceptibles en términos de productividad. Y tres años después, allí estábamos 3 desarrolladores competentes 3, necesitando una tarde entera para fabricar un formulario, un dolor de cabeza, unas ganas de llorar y un apetitoso perolo de sopa de rana. Ancas de batracio deconstruídas en salsa de desarrollador.

¿La conclusión? Parece ser que hemos estado viviendo una alucinación colectiva, nos hemos engañado los unos a los otros, nos hemos metido en una espiral de pérdida de productividad tan gradual como imparable, igual que la pobre rana que acaba cociéndose sin siquiera darse cuenta. El emperador está desnudo, y ha bastado un proyecto suficientemente simple e inocente (como un niño) para gritarlo a los cuatro vientos. No tiene sentido testear exhaustivamente una aplicación, sólo sirve para perder el tiempo.
Que levanten la mano los inocentones que piensen que el post acaba aquí =;-)
Esa conclusión puede ser una verdad clara y confortable, como las que necesitas en momentos de desasosiego, pero tiene mucho de equivocada. Ha habido en mi discurso unos cuantos argumentos algo mentirosos:
Teniendo esto en cuenta, la conclusión no es tan clara y confortable, y además no es nada novedosa, y es que no hay herramientas ni técnicas correctas, sino herramientas y técnicas apropiadas para una tarea concreta. ¿Necesitábamos alforjas para este viaje? Probablemente no, pero puede servirnos para recalcar más aún la importancia de evaluar cómo vamos a enfocar cada proyecto, y no dejarnos llevar por la inercia. Aplicar un enfoque de testing tan exhaustivo a un proyecto simple y tan limitado en el tiempo pudo ser un EPIC FAIL (lo fue), pero eso no significa que en otro proyecto lo sea. Y de hecho, creo que en algunos (por ejemplo el nuestro actual) el EPIC FAIL sería el enfoque contrario.
El emperador está bien vestido y abrigado, lo que pasa es que el sábado fue a la playa y pasó un calor de cojones el pobre ;-)
basehttp://porras.lacoctelera.net/feeds/rss2/posts
Amazon Flexible Payments Service is a payments service offered by Amazon that's focused solely at developers. Using Amazon FPS, you can accept payments on your sites from selling goods and services, donations, recurring payments, etc. You get the benefit of easier interaction with the millions of existing Amazon customers and access to Amazon's proven fraud detection platform. Warning: Only businesses with a US-based credit card can sign up for Amazon FPS!
Rails developer C. Scott Andreas wanted to use Amazon FPS for his own project but found that Amazon's existing examples was written for Rails 1.2.3 and was pretty ugly. So he's developed aws_fps (Github repository), an up to date Rails plugin that takes care of "the nuts and bolts of interfacing with Amazon's FPS." He's very keen to point out, however, that it's not recommended for production use and that if you want to use it, you need to read through the source code and be comfortable with how it operates (and tweak it to your own liking).
Support from: Brightbox; - Europe's leading provider of Ruby on Rails hosting. Now with Phusion Passenger support, each Brightbox server comes with access to a managed MySQL cluster and redundant SAN storage. Brightbox also provides managed services for large scale applications and dedicated clusters.
Just after the discovery of radium, by Pierre and Marie Curie, this chemical element became so popular that soon it was put in some foods, creams and even water, exposing many people to radiation. Minute dilutions of radium were added to tea, health tonics, ice creams, lipsticks, bath salts, costumes that glowed in the dark, and so forth. Radium was once an additive in products like toothpaste, hair creams, and even food items due to its supposed curative powers. Such products soon fell out of vogue and were prohibited by authorities in many countries, after it was discovered they could have serious adverse health effects [1].
Radithor was a well known patent medicine/snake oil that consisted of triple distilled water containing at a minimum 1 microcurie each of the Radium 226 and 228 isotopes. Radithor was manufactured from 1918 - 1928 by the Bailey Radium Laboratories. It was advertised as a "Perpetual Sunshine" and was said to cure stomach cancer, mental illness, and restore sexual vigor and vitality. An American industrialist, Eben Byers, drank a bottle each day for four years, at the end of which he died in excruciating pain from cancer of the jaw as his facial bones disintegrated. [1]
In the early 1930s, this time in France, the industry launched a cosmetic brand Tho-Radia "for pharmaceutical products, beauty products and perfumes." The cream, with a base of thorium and radium, had great success in Paris with promising curative and beautifying properties. [1]
Ceramic jars which added radioactivity (radon) to drinking water became also very popular in those years. Revigator was probably the most popular device developed in the United States to add radon to drinking water. As the brochure stated, "Results overcome doubts." "The millions of tiny rays that are continuously given off by this ore penetrate the water and form this great HEALTH ELEMENT--RADIO-ACTIVITY. All the next day the family is provided with two gallons of real, healthful radioactive water . . . nature's way to health." [1]
Doramad radioactive toothpaste was produced during World War II by Auergesellschaft of Berlin. The back of the tube reads: "Its radioactive radiation increases the defenses of teeth and gums. The cells are loaded with new life energy, the destroying effect of bacteria is hindered. ... It gently polishes the dental enamel so it turns white and shiny". [1]
Radiendocrinator was intended to be placed over the endocrine glands, "which have so masterful a control over life and bodily health." As one example of its use, men were advised "to put this instrument under the scrotum" ant to "wear it at night". [1]
Radium Chocolate manufactured by Burk & Braun, were sold at Germany from 1931 to 1936 and it was advertised for its rejuvenation power.
Produced by the Home Products Company of Denver, Colorado, these suppositories were guaranteed to contain real radium - and probably did. According to the brochure, "Weak Discouraged Men" would feel much better with this suppositories. All Home Product customer orders were shipped in a plain wrapper for confidentiality.[1]
On the other hand, the term "Radium" was incorporated into the brand names of any number of products even when these products didn't actually contain radium. These "Radium cigarrettes", for example, made no claim that they incorporated radioactive material. You can see some more fake radium products like this here.Netcraft acaba de publicar su informe de enero de 2008 sobre qué servidores web se utilizan en internet. Aunque no hay sorpresas que señalar si comparamos el informe con los de meses anteriores, sí que hay varios datos que, por mi desconocimiento, me han llamado la atención.
Este es el top 7 de los servidores web más utilizados:
| Apache | 50,61 |
| Microsoft IIS | 35,81 |
| Google GFE | 5,33 |
| lighttpd | 0,99 |
| nginx | 0,54 |
| Sun | 0,36 |
Los porcentajes de la tabla han sido calculados teniendo en cuenta el número de servidores totales, es decir, suponiendo que cada dominio equivale a un servidor. En el informe también hay datos de los servidores activos, es decir, aquellos dominios que no tienen una mera página de parking.
Pues bien, los datos que me han llamado la atención son:
Con estos datos hay otra cosa que me sorprende. Si hay unos 150 millones de servidores web, de los cuales están activos unos 75 millones y el puesto en el ranking de Alexa de este blog es ahora mismo de 2.290.797, eso quiere decir que este blog está entre el 3% de servidores web más visitados de todo internet. Y dando un paso más, si este modesto blog, que tiene unas 40 visitas diarias, está entre el 3% de webs más visitadas, ¿cuántas visitas tiene una web que se encuentre en el percentil 50? Está claro que estamos ante una cola muy larga.
Actualización: leo en la propia web de Alexa que, al calcularse el ranking mediante un muestreo estadístico, las posiciones por encima de 100.000 no son nada fiables. Así que tomaos el último párrafo con humor.
Use Unfuddle? If you do and you see this error trying to clone a repository, it may be because:
This error looks to be happening because you are not explicitly involved in the project with which this repository is associated. You should note that even account administrators will need to be "involved" in a project in order to receive permissions to repositories associated with that project. In other words, if you add yourself to the project you should be able to connect to the repository.Thanks to Unfuddle founder David Croswell for the solution. Worked like a charm.
IamTHEvilONE wrote:Mike,
that's because GHO is not directly supported. You'll need to use Ghost to export the GHO into the virtual disk format (sv2i or v2i).
Or, ghost the image inside a virtual machine as if it were physical and then use the reconfigure option on the virtual machine to make it bootable.
I am familiar with Ghost but not VMware:
1) How do i convert the image from GHO to sv2i or v2i with Ghost? I have Ghost Solution suite 2.5 and none of the applications in the suite allow me to do what you have suggested? also, why does VMware converter say that it supports gho files if it does not???
2) "Ghost the image inside a virtual machine as if it were physical and then use the reconfigure option on the virtual machine to make it bootable" Can you please explain in more detail how to do this? Sounds like it requires a boot disk prior to imaging the gho file?
Version 0.8.5 strongly improves the reliability of big uploads (big pictures, lots of pictures, lots of pictures in one set, long time for upload, etc.).
Please try again with the new version.
Question: I have been trying to use your tutorial on the NetStream.send function and am getting frustrated. I have been researching this for the past couple of days and not finding any answers.
[More]
From Sang-bum at Samsung -
I am happy to announce that a patch for a new emulator platform Goldfish (QEMU 0.82 based Android emulator) is released at wiki.xensource.com/xenwiki/XenARM.
basehttp://blog.xen.org/index.php/feed/





To create an input method (IME) for entering text into text fields and other Views, you need to extend android.inputmethodservice.InputMethodService. This API provides much of the basic implementation for an input method, in terms of managing the state and visibility of the input method and communicating with the currently visible activity.
A good starting point would be the SoftKeyboard sample code provided as part of the SDK. Modify this code to start building your own input method.
An input method is packaged like any other application or service. In the AndroidManifest.xml file, you declare the input method as a service, with the appropriate intent filter and any associated meta data:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.fastinput"> <application android:label="@string/app_label">If your input method allows the user to tweak some settings, you should provide a settings activity that can be launched from the Settings application. This is optional and you may choose to provide all user settings directly in your IME's UI.
The typical life-cycle of an InputMethodService looks like this:
There are 2 main visual elements for an input method??the input view and the candidates view. You don't have to follow this style though, if one of them is not relevant to your input method experience.
Input ViewThis is where the user can input text either in the form of keypresses, handwriting or other gestures. When the input method is displayed for the first time, InputMethodService.onCreateInputView() will be called. Create and return the view hierarchy that you would like to display in the input method window.
Candidates ViewThis is where potential word corrections or completions are presented to the user for selection. Again, this may or may not be relevant to your input method and you can return null from calls to InputMethodService.onCreateCandidatesView(), which is the default behavior.
Designing for the different Input TypesAn application's text fields can have different input types specified on them, such as free form text, numeric, URL, email address and search. When you implement a new input method, you need to be aware of the different input types. Input methods are not automatically switched for different input types and so you need to support all types in your IME. However, the IME is not responsible for validating the input sent to the application. That's the responsibility of the application.
For example, the LatinIME provided with the Android platform provides different layouts for text and phone number entry:
InputMethodService.onStartInputView() is called with an EditorInfo object that contains details about the input type and other attributes of the application's text field.
(EditorInfo.inputType & EditorInfo.TYPE_CLASS_MASK) can be one of many different values, including:
See android.text.InputType for more details.
EditorInfo.inputType can contain other masked bits that indicate the class variation and other flags. For example, TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_URI or TYPE_TEXT_FLAG_AUTO_COMPLETE.
Password fieldsPay specific attention when sending text to password fields. Make sure that the password is not visible within your UI - in neither the input view nor the candidates view. And do not save the password anywhere without explicitly informing the user.
Landscape vs. portraitThe UI needs to be able to scale between landscape and portrait orientations. In non-fullscreen IME mode, leave sufficient space for the application to show the text field and any associated context. Preferably, no more than half the screen should be occupied by the IME. In fullscreen IME mode this is not an issue.
Sending text to the applicationThere are two ways to send text to the application. You can either send individual key events or you can edit the text around the cursor in the application's text field.
To send a key event, you can simply construct KeyEvent objects and call InputConnection.sendKeyEvent(). Here are some examples:
InputConnection ic = getCurrentInputConnection(); long eventTime = SystemClock.uptimeMillis(); ic.sendKeyEvent(new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)); ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime, KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));Or use the convenience method:
InputMethodService.sendDownUpKeyEvents(keyEventCode);Note: It is recommended to use the above method for certain fields such as phone number fields because of filters that may be applied to the text after each key press. Return key and delete key should also be sent as raw key events for certain input types, as applications may be watching for specific key events in order to perform an action.
When editing text in a text field, some of the more useful methods on android.view.inputmethod.InputConnection are:
For example, let's say the text "Fell" is to the left of the cursor. And you want to replace it with "Hello!":
InputConnection ic = getCurrentInputConnection(); ic.deleteSurroundingText(4, 0); ic.commitText("Hello", 1); ic.commitText("!", 1);Composing text before committingIf your input method does some kind of text prediction or requires multiple steps to compose a word or glyph, you can show the progress in the text field until the user commits the word and then you can replace the partial composition with the completed text. The text that is being composed will be highlighted in the text field in some fashion, such as an underline.
InputConnection ic = getCurrentInputConnection(); ic.setComposingText("Composi", 1); ... ic.setComposingText("Composin", 1); ... ic.commitText("Composing ", 1);Even though the input method window doesn't have explicit focus, it receives hard key events first and can choose to consume them or forward them along to the application. For instance, you may want to consume the directional keys to navigate within your UI for candidate selection during composition. Or you may want to trap the back key to dismiss any popups originating from the input method window. To intercept hard keys, override InputMethodService.onKeyDown() and InputMethodService.onKeyUp(). Remember to call super.onKey* if you don't want to consume a certain key yourself.
Other considerationsFor a real world example, with support for multiple input types and text prediction, see the LatinIME source code. The Android 1.5 SDK also includes a SoftKeyboard sample as well.
Learn about Android 1.5 and more at Google I/O. Members of the Android team will be there to give a series of in-depth technical sessions and to field your toughest questions.
To create an input method (IME) for entering text into text fields and other Views, you need to extend android.inputmethodservice.InputMethodService. This API provides much of the basic implementation for an input method, in terms of managing the state and visibility of the input method and communicating with the currently visible activity.
A good starting point would be the SoftKeyboard sample code provided as part of the SDK. Modify this code to start building your own input method.
An input method is packaged like any other application or service. In the AndroidManifest.xml file, you declare the input method as a service, with the appropriate intent filter and any associated meta data:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.fastinput"> <application android:label="@string/app_label">If your input method allows the user to tweak some settings, you should provide a settings activity that can be launched from the Settings application. This is optional and you may choose to provide all user settings directly in your IME's UI.
The typical life-cycle of an InputMethodService looks like this:
There are 2 main visual elements for an input method??the input view and the candidates view. You don't have to follow this style though, if one of them is not relevant to your input method experience.
Input ViewThis is where the user can input text either in the form of keypresses, handwriting or other gestures. When the input method is displayed for the first time, InputMethodService.onCreateInputView() will be called. Create and return the view hierarchy that you would like to display in the input method window.
Candidates ViewThis is where potential word corrections or completions are presented to the user for selection. Again, this may or may not be relevant to your input method and you can return null from calls to InputMethodService.onCreateCandidatesView(), which is the default behavior.
Designing for the different Input TypesAn application's text fields can have different input types specified on them, such as free form text, numeric, URL, email address and search. When you implement a new input method, you need to be aware of the different input types. Input methods are not automatically switched for different input types and so you need to support all types in your IME. However, the IME is not responsible for validating the input sent to the application. That's the responsibility of the application.
For example, the LatinIME provided with the Android platform provides different layouts for text and phone number entry:
InputMethodService.onStartInputView() is called with an EditorInfo object that contains details about the input type and other attributes of the application's text field.
(EditorInfo.inputType & EditorInfo.TYPE_CLASS_MASK) can be one of many different values, including:
See android.text.InputType for more details.
EditorInfo.inputType can contain other masked bits that indicate the class variation and other flags. For example, TYPE_TEXT_VARIATION_PASSWORD or TYPE_TEXT_VARIATION_URI or TYPE_TEXT_FLAG_AUTO_COMPLETE.
Password fieldsPay specific attention when sending text to password fields. Make sure that the password is not visible within your UI - in neither the input view nor the candidates view. And do not save the password anywhere without explicitly informing the user.
Landscape vs. portraitThe UI needs to be able to scale between landscape and portrait orientations. In non-fullscreen IME mode, leave sufficient space for the application to show the text field and any associated context. Preferably, no more than half the screen should be occupied by the IME. In fullscreen IME mode this is not an issue.
Sending text to the applicationThere are two ways to send text to the application. You can either send individual key events or you can edit the text around the cursor in the application's text field.
To send a key event, you can simply construct KeyEvent objects and call InputConnection.sendKeyEvent(). Here are some examples:
InputConnection ic = getCurrentInputConnection(); long eventTime = SystemClock.uptimeMillis(); ic.sendKeyEvent(new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)); ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime, KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0, KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));Or use the convenience method:
InputMethodService.sendDownUpKeyEvents(keyEventCode);Note: It is recommended to use the above method for certain fields such as phone number fields because of filters that may be applied to the text after each key press. Return key and delete key should also be sent as raw key events for certain input types, as applications may be watching for specific key events in order to perform an action.
When editing text in a text field, some of the more useful methods on android.view.inputmethod.InputConnection are:
For example, let's say the text "Fell" is to the left of the cursor. And you want to replace it with "Hello!":
InputConnection ic = getCurrentInputConnection(); ic.deleteSurroundingText(4, 0); ic.commitText("Hello", 1); ic.commitText("!", 1);Composing text before committingIf your input method does some kind of text prediction or requires multiple steps to compose a word or glyph, you can show the progress in the text field until the user commits the word and then you can replace the partial composition with the completed text. The text that is being composed will be highlighted in the text field in some fashion, such as an underline.
InputConnection ic = getCurrentInputConnection(); ic.setComposingText("Composi", 1); ... ic.setComposingText("Composin", 1); ... ic.commitText("Composing ", 1);Even though the input method window doesn't have explicit focus, it receives hard key events first and can choose to consume them or forward them along to the application. For instance, you may want to consume the directional keys to navigate within your UI for candidate selection during composition. Or you may want to trap the back key to dismiss any popups originating from the input method window. To intercept hard keys, override InputMethodService.onKeyDown() and InputMethodService.onKeyUp(). Remember to call super.onKey* if you don't want to consume a certain key yourself.
Other considerationsFor a real world example, with support for multiple input types and text prediction, see the LatinIME source code. The Android 1.5 SDK also includes a SoftKeyboard sample as well.
Learn about Android 1.5 and more at Google I/O. Members of the Android team will be there to give a series of in-depth technical sessions and to field your toughest questions.