Skip to content

Commit

Permalink
Merge pull request #2 from confluentinc/system_tests
Browse files Browse the repository at this point in the history
Bootstrap Kafka system tests
  • Loading branch information
Ishiihara committed Apr 24, 2015
2 parents 5397d3c + 81e4156 commit f1914c3
Show file tree
Hide file tree
Showing 17 changed files with 1,028 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ config/server-*
config/zookeeper-*
core/data/*
gradle/wrapper/*

results
tests/results
.ducktape
tests/.ducktape
51 changes: 48 additions & 3 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ require 'socket'
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

# Mode
mode = "kafka_cluster"

# General config
enable_dns = false
ram_megabytes = 1280
num_workers = 0 # Generic workers that get the code, but don't start any services
num_zookeepers = 1
num_brokers = 3
num_workers = 0 # Generic workers that get the code, but don't start any services
ram_megabytes = 1280

# EC2
ec2_access_key = ENV['AWS_ACCESS_KEY']
ec2_secret_key = ENV['AWS_SECRET_KEY']
ec2_session_token = ENV['AWS_SESSION_TOKEN']
ec2_keypair_name = nil
ec2_keypair_file = nil

Expand All @@ -49,6 +53,29 @@ if File.exists?(local_config_file) then
eval(File.read(local_config_file), binding, "Vagrantfile.local")
end

if mode == "test"
num_zookeepers = 0
num_brokers = 0
end

# This is a horrible hack to work around bad interactions between
# vagrant-hostmanager and vagrant-aws/vagrant's implementation. Hostmanager
# wants to update the /etc/hosts entries, but tries to do so even on nodes that
# aren't up (e.g. even when all nodes are stopped and you run vagrant
# destroy). Because of the way the underlying code in vagrant works, it still
# tries to communicate with the node and has to wait for a very long
# timeout. This modifies the update to check for hosts that are not created or
# stopped, skipping the update in that case since it's impossible to update
# nodes in that state.
Object.const_get("VagrantPlugins").const_get("HostManager").const_get("HostsFile").class_eval do
alias_method :old_update_guest, :update_guest
def update_guest(machine)
state_id = machine.state.id
return if state_id == :not_created || state_id == :stopped
old_update_guest(machine)
end
end

# TODO(ksweeney): RAM requirements are not empirical and can probably be significantly lowered.
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.hostmanager.enabled = true
Expand Down Expand Up @@ -84,13 +111,31 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
override.vm.box = "dummy"
override.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"

override.hostmanager.ignore_private_ip = true
cached_addresses = {}
# Use a custom resolver that SSH's into the machine and finds the IP address
# directly. This lets us get at the private IP address directly, avoiding
# some issues with using the default IP resolver, which uses the public IP
# address.
override.hostmanager.ip_resolver = proc do |vm, resolving_vm|
if !cached_addresses.has_key?(vm.name)
state_id = vm.state.id
if state_id != :not_created && state_id != :stopped && vm.communicate.ready?
vm.communicate.execute("/sbin/ifconfig eth0 | grep 'inet addr' | tail -n 1 | egrep -o '[0-9\.]+' | head -n 1 2>&1") do |type, contents|
cached_addresses[vm.name] = contents.split("\n").first[/(\d+\.\d+\.\d+\.\d+)/, 1]
end
else
cached_addresses[vm.name] = nil
end
end
cached_addresses[vm.name]
end

override.ssh.username = ec2_user
override.ssh.private_key_path = ec2_keypair_file

aws.access_key_id = ec2_access_key
aws.secret_access_key = ec2_secret_key
aws.session_token = ec2_session_token
aws.keypair_name = ec2_keypair_name

aws.region = ec2_region
Expand Down
11 changes: 11 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Vagrantfile.local

.idea/

*.pyc
*.ipynb

.DS_Store

.ducktape
results/
44 changes: 44 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
System Integration & Performance Testing
========================================

This directory contains Kafka system integration and performance tests.
[Ducktape](https://github.com/confluentinc/ducktape) is used to run the tests.

Ducktape is a distributed testing framework which provides test runner,
result reporter and utilities to pull up and tear down services. It automatically
discovers tests from a directory and generate an HTML report for each run.

To run the tests:

1. Build a specific branch of Kafka

$ cd kafka
$ git checkout $BRANCH
$ gradle
$ ./gradlew jar

2. Setup a testing cluster. You can use Vagrant to create a cluster of local
VMs or on EC2. Configure your Vagrant setup by creating the file
`Vagrantfile.local` in the directory of your Kafka checkout. At a minimum
, you *MUST* set `mode = "test"` and the value of `num_workers` high enough for
the test you're trying to run. If you run on AWS, you also need to set
enable_dns = true.

3. Bring up the cluster, making sure you have enough workers. For Vagrant,
use `vagrant up`. If you want to run on AWS, use `vagrant up
--provider=aws --no-parallel`.
4. Install ducktape:

$ git clone https://github.com/confluentinc/ducktape
$ cd ducktape
$ pip install ducktape
5. Run the system tests using ducktape, you can view results in the `results`
directory.

$ cd tests
$ ducktape tests
6. To iterate/run again if you made any changes:

$ cd kafka
$ ./gradlew jar
$ vagrant rsync # Re-syncs build output to cluster
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

3 changes: 3 additions & 0 deletions tests/aws/aws-access-keys-commands
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export AWS_ACCESS_KEY=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ducttape-master | grep AccessKeyId | awk -F\" '{ print $4 }'`
export AWS_SECRET_KEY=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ducttape-master | grep SecretAccessKey | awk -F\" '{ print $4 }'`
export AWS_SESSION_TOKEN=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ducttape-master | grep Token | awk -F\" '{ print $4 }'`
9 changes: 9 additions & 0 deletions tests/aws/aws-example-Vagrantfile.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ec3_instance_type = "m3.medium"
enable_dns = true
mode = "test"
num_workers = 1
ec2_keypair_name =
ec2_keypair_file =
ec2_security_groups = ['ducttape-insecure']
ec2_region = 'us-west-2'
ec2_ami = "ami-29ebb519"
57 changes: 57 additions & 0 deletions tests/aws/aws-init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

# This script should be run once on your aws test driver machine before
# attempting to run any ducktape tests

# Install dependencies
sudo apt-get install -y maven openjdk-6-jdk build-essential \
ruby-dev zlib1g-dev realpath python-setuptools

base_dir=`dirname $0`/..

if [ -z `which vagrant` ]; then
echo "Installing vagrant..."
wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.7.2_x86_64.deb
sudo dpkg -i vagrant_1.7.2_x86_64.deb
rm -f vagrant_1.7.2_x86_64.deb
fi

# Install necessary vagrant plugins
# Note: Do NOT install vagrant-cachier since it doesn't work on AWS and only
# adds log noise
vagrant_plugins="vagrant-aws vagrant-hostmanager"
existing=`vagrant plugin list`
for plugin in $vagrant_plugins; do
echo $existing | grep $plugin > /dev/null
if [ $? != 0 ]; then
vagrant plugin install $plugin
fi
done

# Create Vagrantfile.local as a convenience
if [ ! -e "$base_dir/Vagrantfile.local" ]; then
cp $base_dir/aws/aws-example-Vagrantfile.local $base_dir/Vagrantfile.local
fi

gradle="gradle-2.2.1"
if [ -z `which gradle` ] && [ ! -d $base_dir/$gradle ]; then
if [ ! -e $gradle-bin.zip ]; then
wget https://services.gradle.org/distributions/$gradle-bin.zip
fi
unzip $gradle-bin.zip
rm -rf $gradle-bin.zip
mv $gradle $base_dir/$gradle
fi

# Ensure aws access keys are in the environment when we use a EC2 driver machine
LOCAL_HOSTNAME=$(hostname -d)
if [[ ${LOCAL_HOSTNAME} =~ .*\.compute\.internal ]]; then
grep "AWS ACCESS KEYS" ~/.bashrc > /dev/null
if [ $? != 0 ]; then
echo "# --- AWS ACCESS KEYS ---" >> ~/.bashrc
echo ". `realpath $base_dir/aws/aws-access-keys-commands`" >> ~/.bashrc
echo "# -----------------------" >> ~/.bashrc
source ~/.bashrc
fi
fi

Empty file added tests/services/__init__.py
Empty file.
Loading

0 comments on commit f1914c3

Please sign in to comment.