3. #CCCEU14 | #CloudStackWorks
About Me
⢠Cloud Architect @ CloudOps
⢠Work full time with Apache CloudStack
â As user
â As contributor
⢠Apache CloudStack PMC member
⢠Ruby and Chef Enthusiast
4. #CCCEU14 | #CloudStackWorks
About CloudOps
⢠CloudOps builds and operates CloudStack
based clouds of all shapes and sizes
⢠Develops cloud infrastructure solutions and
operational models
⢠24x7x365 managed service for CloudStack
based cloud infrastructures
⢠Customers are global
⢠Based in Montreal, Canada
5. #CCCEU14 | #CloudStackWorks
Current state of the project
⢠Proof of concept
⢠Support
â VPC
â Port Forwarding
â Create snapshot
â Create template from snapshot
â Various zone features validation.
7. #CCCEU14 | #CloudStackWorks
What Iâm trying to solve
⢠We have multiple LAB CloudStack
installations running multiple versions and
configurations. Need to validate their
usability.
⢠CloudStack Release Upgrade tests on real
hardware.
8. #CCCEU14 | #CloudStackWorks
Monitoring is not enough
⢠Monitoring can tell if there is enough
Secondary storage. But cannot tell if itâs
usable in CloudStack.
⢠Monitoring cannot tell if Featured
templates are usable.
10. #CCCEU14 | #CloudStackWorks
I did not tried Marvin
1. Look like it provision CloudStack configs
and tests, right?
2. Defining tests require coding (from user
perspective)
3. Could hardly benefit from ServerSpec,
specinfra or test-kitchen
https://cwiki.apache.org/confluence/display/CLOUDSTACK/Marvin+-+Testing+with+Python
12. #CCCEU14 | #CloudStackWorks
The purposes
⢠Test existing CloudStack installation
⢠Validate functionality of a Cloud
⢠Advanced tests:
â Port-forwarding rules into VPC
â Create Instance from Snapshot
â Create Template from Snapshot
13. #CCCEU14 | #CloudStackWorks
About cloudstack_spec
⢠Ruby Rspec based
⢠Based on ServerSpec
⢠Test case easy to define
⢠Use:
â cloudstack_ruby_client
â serverspec
â specinfra
⢠Code maturity: under heavy dev
14. #CCCEU14 | #CloudStackWorks
It is not
⢠Deployment tool
⢠Replacement to Marvin
⢠Monitoring plugin/tool
⢠Reporting tool
17. #CCCEU14 | #CloudStackWorks
Zone
require 'spec_helper'
describe zone do
it { should exist }
it { should be_allocated }
its(:local_storage) { should be_set }
its(:security_group) { should_not be_set }
its(:network_type) { should match("Advanced") }
end
18. #CCCEU14 | #CloudStackWorks
Zone
require 'spec_helper'
describe zone do
it { should exist }
it { should be_allocated }
its(:local_storage) { should be_set }
its(:security_group) { should_not be_set }
its(:network_type) { should match("Advanced") }
end
Do I have a zone?
19. #CCCEU14 | #CloudStackWorks
Zone
require 'spec_helper'
describe zone do
it { should exist }
it { should be_allocated }
its(:local_storage) { should be_set }
its(:security_group) { should_not be_set }
its(:network_type) { should match("Advanced") }
end
The zone is
enabled
(allocated)?
20. #CCCEU14 | #CloudStackWorks
Zone
require 'spec_helper'
describe zone do
it { should exist }
it { should be_allocated }
its(:local_storage) { should be_set }
its(:security_group) { should_not be_set }
its(:network_type) { should match("Advanced") }
end
rspec_its: eval
method attributes
21. #CCCEU14 | #CloudStackWorks
Zone
require 'spec_helper'
describe zone do
it { should exist }
it { should be_allocated }
its(:local_storage) { should be_set }
its(:security_group) { should_not be_set }
its(:network_type) { should match("Advanced") }
end
Easy valid on false
22. #CCCEU14 | #CloudStackWorks
Zone
require 'spec_helper'
describe zone do
it { should exist }
it { should be_allocated }
its(:local_storage) { should be_set }
its(:security_group) { should_not be_set }
its(:network_type) { should match("Advanced") }
end
Rspec string
validation
28. #CCCEU14 | #CloudStackWorks
System vm tests
%w(consoleproxy secondarystoragevm).each do |svm|
describe system_vm(svm) do
it { should exist }
it { should be_running }
it { should be_reachable }
end
end
32. #CCCEU14 | #CloudStackWorks
vpc_spec.rb
describe vpc('spec-vpc1') do
it { should be_created }
it { should exist }
it { should be_ready }
it { should be_reachable }
describe vpc_tier('tier11') do
it { should be_created }
it { should exist }
describe virtual_machine('vm-test1') do
it { should be_created }
it { should_not be_reachable }
it { should exist }
it { should be_running }
its(:open_pf_ssh) { should be_set }
context 'With port forwarding' do
it { should be_reachable.with( :port => 22, :proto => 'tcp' ) }
end
end
end
end
33. #CCCEU14 | #CloudStackWorks
vpc_spec.rb
describe vpc('spec-vpc1') do
it { should be_created }
it { should exist }
it { should be_ready }
it { should be_reachable }
describe vpc_tier('tier11') do
it { should be_created }
it { should exist }
describe virtual_machine('vm-test1') do
it { should be_created }
it { should_not be_reachable }
it { should exist }
it { should be_running }
its(:open_pf_ssh) { should be_set }
context 'With port forwarding' do
it { should be_reachable.with( :port => 22, :proto => 'tcp' ) }
end
end
end
end
be_created
Create the object
34. #CCCEU14 | #CloudStackWorks
vpc_spec.rb
describe vpc('spec-vpc1') do
it { should be_created }
it { should exist }
it { should be_ready }
it { should be_reachable }
describe vpc_tier('tier11') do
it { should be_created }
it { should exist }
describe virtual_machine('vm-test1') do
it { should be_created }
it { should_not be_reachable }
it { should exist }
it { should be_running }
its(:open_pf_ssh) { should be_set }
context 'With port forwarding' do
it { should be_reachable.with( :port => 22, :proto => 'tcp' ) }
end
end
end
end
be_reachable
Ping test
35. #CCCEU14 | #CloudStackWorks
vpc_spec.rb
describe vpc('spec-vpc1') do
it { should be_created }
it { should exist }
it { should be_ready }
it { should be_reachable }
describe vpc_tier('tier11') do
it { should be_created }
it { should exist }
describe virtual_machine('vm-test1') do
it { should be_created }
it { should_not be_reachable }
it { should exist }
it { should be_running }
its(:open_pf_ssh) { should be_set }
context 'With port forwarding' do
it { should be_reachable.with( :port => 22, :proto => 'tcp' ) }
end
end
end
end
be_reachable
Tcp connection test
Using Public IP
42. #CCCEU14 | #CloudStackWorks
Custom Rspec matcher
# If the zone is allocated (Enabled)
RSpec::Matchers.define :be_allocated do |expected|
match do |actual|
actual.allocated? == true
end
failure_message do |actual|
"status: #{actual.allocated?}"
end
description do
"be allocated (Enabled)"
end
failure_message_when_negated do |actual|
"Status: #{actual}"
end
end
43. #CCCEU14 | #CloudStackWorks
resources (Test cases)
⢠Test cases are:
â Objects to test are Ruby Class:
CloudstackSpec::Resource::Snapshot
â Unit tests are Ruby Methods inside Class:
self.exist?
45. #CCCEU14 | #CloudStackWorks
Future improvements
⢠Provide as Gem
⢠Auto config, same as Serverspec
⢠More tests
⢠Better error message
⢠Add compatibility with ServerSpec
⢠test-kitchen compatibility?
Perform a complete usability test suite on an existing cloud.
Most likely for things related to:
Storage
Networking
VR, vpn, aclsâŚ
Usually installing cloudstack using Chef
Monitoring have is limit. It can monitor CloudStack ressources but hardly monitor usability of CloudStack.
Iâm not a Python developer
If I want to use Marvin to test existing Cloud, I need to build my own Python scripts.
We have multiple deployment of CloudStack in a lab that something have Power Interruption.
Need a way to test our used case against new ACS release
Iâm expecting to certifiy our deployed cloud at some point not just troubleshooting lab.
No need to specify a zone, It will use the first one it find.
Simple test definition
The zone is Enabled
Return true/false for zone params using rspec_its its eval method attributes.
Negate a configuration ( valid if not)
Reuse rspec matcher for dev simplicity
Quick Information on the system under test
Test results with color
Execution time and results
And test each process to make sure they exist are are properly created.
So, no code as to be written to perform complexe validation test.
something is wrong
Async job in progress, have to wait the CloudStack Async job is completed.
Validation not just on running or not.
Failure provide bit of information
Creating tests in Ruby are not too complicated, it is the mapping
Need to be able to test from inside an Instance, to validate PortForwarding rules, Firewall policies
More advanced tests as VPN connections, Ipsec tunnel.
After a Chef run that deployed CloudStack, should test that the new Cloud is working