stormforge-ruby 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +6 -0
- data/bin/stormforge +18 -0
- data/examples/README.md +27 -0
- data/examples/Stormfile +1 -0
- data/examples/demo_case.rb +12 -0
- data/examples/file_upload.rb +28 -0
- data/examples/fixtures/requests.csv +2 -0
- data/examples/fixtures/users.csv +2 -0
- data/examples/simple_and_long.rb +12 -0
- data/examples/simple_and_short.rb +12 -0
- data/examples/test_case_definition_v1.rb +206 -0
- data/lib/core_ext/fixnum.rb +20 -0
- data/lib/stormforge.rb +39 -0
- data/lib/stormforge/client.rb +227 -0
- data/lib/stormforge/dsl.rb +4 -0
- data/lib/stormforge/dsl/test_case.rb +9 -0
- data/lib/stormforge/dsl/test_case/attribute_access.rb +19 -0
- data/lib/stormforge/dsl/test_case/cloud.rb +33 -0
- data/lib/stormforge/dsl/test_case/data_source.rb +49 -0
- data/lib/stormforge/dsl/test_case/data_source/file_fixture.rb +104 -0
- data/lib/stormforge/dsl/test_case/data_source/random_number.rb +64 -0
- data/lib/stormforge/dsl/test_case/data_source/random_string.rb +52 -0
- data/lib/stormforge/dsl/test_case/definition.rb +128 -0
- data/lib/stormforge/dsl/test_case/session.rb +77 -0
- data/lib/stormforge/registry.rb +23 -0
- data/lib/stormforge/version.rb +3 -0
- data/lib/thor/generators/init.rb +14 -0
- data/lib/thor/generators/templates/Stormfile +15 -0
- data/lib/thor/main.rb +79 -0
- data/lib/thor/storm_forge_base.rb +46 -0
- data/lib/thor/testcase.rb +23 -0
- data/lib/thor/testrun.rb +75 -0
- data/spec/client_spec.rb +4 -0
- data/spec/dsl/test_case/attribute_access_spec.rb +46 -0
- data/spec/dsl/test_case/cloud_spec.rb +15 -0
- data/spec/dsl/test_case/data_source/file_fixture_spec.rb +101 -0
- data/spec/dsl/test_case/data_source/random_number_spec.rb +51 -0
- data/spec/dsl/test_case/data_source/random_string_spec.rb +33 -0
- data/spec/dsl/test_case/data_source_spec.rb +12 -0
- data/spec/dsl/test_case/definition_spec.rb +107 -0
- data/spec/dsl/test_case/session_spec.rb +102 -0
- data/spec/dsl/test_case_integration_spec.rb +148 -0
- data/spec/dsl/test_case_spec.rb +8 -0
- data/spec/fixtures/ip_addresses.csv +1 -0
- data/spec/fixtures/slug.csv +1 -0
- data/spec/fixtures/users.csv +2 -0
- data/spec/registry_spec.rb +34 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/stormforger_spec.rb +13 -0
- data/stormforge_ruby.gemspec +38 -0
- metadata +344 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
class StormForge::Thor::Base < Thor
|
2
|
+
private
|
3
|
+
|
4
|
+
def client
|
5
|
+
error "WARNING! Disabling SSL certificate verification is not recommended. Proceed with caution!" if options[:skip_ssl_verify]
|
6
|
+
|
7
|
+
@client ||= StormForge::Client.new({
|
8
|
+
user: authentication["email"],
|
9
|
+
token: authentication["authentication_token"],
|
10
|
+
dev_mode: dev_mode?,
|
11
|
+
skip_ssl_verify: options[:skip_ssl_verify]
|
12
|
+
})
|
13
|
+
end
|
14
|
+
|
15
|
+
def require_stormfile!
|
16
|
+
stormfile = File.expand_path(options[:stormfile])
|
17
|
+
raise Thor::Error, "Stormfile at '#{options[:stormfile]}' not found!" unless File.exists? stormfile
|
18
|
+
load options[:stormfile]
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle_authentication_error(exception)
|
22
|
+
raise Thor::Error, "Authentication error, check your credentials or run 'stormforge auth' again!"
|
23
|
+
end
|
24
|
+
|
25
|
+
def authentication
|
26
|
+
return @authentication if @authentication
|
27
|
+
|
28
|
+
raise Thor::Error, "No authentication file found" unless File.exists? authfile
|
29
|
+
|
30
|
+
auth = JSON.parse(File.read(authfile))
|
31
|
+
|
32
|
+
raise Thor::Error, "Authentication file invalid. Use 'stormforger auth' to generate a new one." unless auth["email"].present? && auth["authentication_token"].present?
|
33
|
+
|
34
|
+
@authentication = auth
|
35
|
+
end
|
36
|
+
|
37
|
+
def authfile
|
38
|
+
path = File.expand_path(options[:authfile])
|
39
|
+
path += ".dev" if dev_mode?
|
40
|
+
path
|
41
|
+
end
|
42
|
+
|
43
|
+
def dev_mode?
|
44
|
+
!!options[:development]
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class StormForge::Thor::Testcase < StormForge::Thor::Base
|
2
|
+
desc "update NAME", "Update test case NAME"
|
3
|
+
def update(name)
|
4
|
+
require_stormfile!
|
5
|
+
|
6
|
+
test_case = StormForge.test_case(name.to_sym)
|
7
|
+
|
8
|
+
raise Thor::Error, "Test case '#{name}' unknown!" unless test_case
|
9
|
+
|
10
|
+
client.create_or_update(test_case)
|
11
|
+
rescue Faraday::Error::ConnectionFailed
|
12
|
+
raise Thor::Error, "StormForger API not available :-/ (connection failed)"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "list", "List all defined test cases"
|
16
|
+
def list
|
17
|
+
require_stormfile!
|
18
|
+
|
19
|
+
StormForge.registry.each_pair do |name, test_case|
|
20
|
+
puts name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/thor/testrun.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
class StormForge::Thor::Testrun < StormForge::Thor::Base
|
2
|
+
desc "list [TEST_CASE]", "List test runs"
|
3
|
+
def list(test_case_slug=nil)
|
4
|
+
require_stormfile!
|
5
|
+
|
6
|
+
test_runs = client.list_test_runs(test_case_slug)["test_runs"]
|
7
|
+
test_case = test_case_slug.present? ? "test case '#{test_case_slug}'" : "all test cases"
|
8
|
+
puts "Test Run ID & Description for #{test_case}"
|
9
|
+
test_runs.each do |test_run|
|
10
|
+
puts "#{test_run["id"].to_s} (#{test_run["state"]}): #{test_run["description"] || '-'}"
|
11
|
+
end
|
12
|
+
rescue Faraday::Error::ConnectionFailed
|
13
|
+
raise Thor::Error, "StormForger API not available :-/ (connection failed)"
|
14
|
+
rescue Faraday::Error::ResourceNotFound
|
15
|
+
raise Thor::Error, "Test case '#{test_case_slug}' not found!"
|
16
|
+
rescue Faraday::Error::ClientError => e
|
17
|
+
if e.response[:status] == 401
|
18
|
+
handle_authentication_error(e)
|
19
|
+
else
|
20
|
+
raise e
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "create TEST_CASE [DESCRIPTION]", "Create a test run"
|
25
|
+
def create(test_case_slug, description="")
|
26
|
+
require_stormfile!
|
27
|
+
|
28
|
+
p client.create_test_run(test_case_slug, description)
|
29
|
+
rescue Faraday::Error::ConnectionFailed
|
30
|
+
raise Thor::Error, "StormForger API not available :-/ (connection failed)"
|
31
|
+
rescue Faraday::Error::ResourceNotFound
|
32
|
+
raise Thor::Error, "Test Run could not be created, test case '#{test_case_slug}' not found!"
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "show TEST_RUN_ID", "Show a test run"
|
36
|
+
def show(test_run_id)
|
37
|
+
require_stormfile!
|
38
|
+
|
39
|
+
test_run = client.fetch_test_run(test_run_id)
|
40
|
+
pp test_run
|
41
|
+
rescue Faraday::Error::ConnectionFailed
|
42
|
+
raise Thor::Error, "StormForger API not available :-/ (connection failed)"
|
43
|
+
rescue Faraday::Error::ResourceNotFound
|
44
|
+
raise Thor::Error, "Test Run #{test_run_id} not found!"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "stats TEST_RUN_ID", "Get stats (WIP)"
|
48
|
+
method_option :stream, type: :boolean, default: true, desc: "WIP: Stream"
|
49
|
+
method_option :limit, type: :numeric, default: 10, desc: "Limit of stats per batch"
|
50
|
+
def stats(test_run_id, since=0)
|
51
|
+
require_stormfile!
|
52
|
+
|
53
|
+
client.test_run_log(test_run_id, since, options[:limit], options[:stream]) do |stats|
|
54
|
+
puts stats.to_json
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "abort TEST_RUN_ID", "Abort a test run"
|
59
|
+
def abort(test_run_id)
|
60
|
+
require_stormfile!
|
61
|
+
|
62
|
+
test_run = client.abort_test_run(test_run_id)
|
63
|
+
puts test_run.inspect
|
64
|
+
rescue Faraday::Error::ConnectionFailed
|
65
|
+
raise Thor::Error, "StormForger API not available :-/ (connection failed)"
|
66
|
+
rescue Faraday::Error::ResourceNotFound
|
67
|
+
raise Thor::Error, "Test Run #{test_run_id} not found"
|
68
|
+
rescue Faraday::Error::ClientError => e
|
69
|
+
if e.response[:status] == 422
|
70
|
+
raise Thor::Error, "Test Run #{test_run_id} cannot be aborted!"
|
71
|
+
else
|
72
|
+
raise e
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class Foo
|
4
|
+
include StormForge::Dsl::TestCase::AttributeAccess
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@attributes = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def available_attributes
|
11
|
+
[:title]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe StormForge::Dsl::TestCase::AttributeAccess do
|
16
|
+
it "should tell if it responds to a given attribute" do
|
17
|
+
foo = Foo.new
|
18
|
+
foo.respond_to?(:title).should == true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be able to set the configured attribute's values (DSL style)" do
|
22
|
+
foo = Foo.new
|
23
|
+
foo.title "new title"
|
24
|
+
foo.title.should == "new title"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be able to set the configured attribute's values via setter" do
|
28
|
+
foo = Foo.new
|
29
|
+
foo.title = "new title"
|
30
|
+
foo.title.should == "new title"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should delegate to super if no specified attribute matches" do
|
34
|
+
foo = Foo.new
|
35
|
+
expect do
|
36
|
+
foo.something
|
37
|
+
end.to raise_error(NoMethodError)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should not allow more than one argument to generated attribute accessors" do
|
41
|
+
foo = Foo.new
|
42
|
+
expect do
|
43
|
+
foo.title "new title", "meh?"
|
44
|
+
end.to raise_error(ArgumentError)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StormForge::Dsl::TestCase::Cloud do
|
4
|
+
describe "Validations" do
|
5
|
+
subject { StormForge::Dsl::TestCase::Cloud.new :aws, Proc.new {} }
|
6
|
+
it { should ensure_inclusion_of(:provider).in_array(StormForge::Dsl::TestCase::Cloud.supported_cloud_providers) }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have security groups" do
|
10
|
+
cloud = StormForge::Dsl::TestCase::Cloud.new :aws do
|
11
|
+
security_groups "sg-12345", "sg-abcdef"
|
12
|
+
end
|
13
|
+
cloud.security_groups.should include("sg-12345", "sg-abcdef")
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StormForge::Dsl::TestCase::DataSource::FileFixture do
|
4
|
+
subject { StormForge::Dsl::TestCase::DataSource::FileFixture }
|
5
|
+
|
6
|
+
describe "Validations" do
|
7
|
+
it "should require a name" do
|
8
|
+
users = subject.new(nil, {})
|
9
|
+
users.valid?
|
10
|
+
users.errors[:name].should be_present
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should default order to :sequentially" do
|
14
|
+
users = subject.new("a name", {})
|
15
|
+
users.order.should == :sequentially
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should require an existing source" do
|
19
|
+
users = subject.new("users", source: "NOT-EXISTING")
|
20
|
+
users.valid?
|
21
|
+
users.errors[:source].should be_present
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should actually check for an existing source" do
|
25
|
+
users = subject.new("users", source: File.join(FIXTURE_PATH, "users.csv"))
|
26
|
+
users.valid?
|
27
|
+
users.errors[:source].should be_blank
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#delimiter" do
|
32
|
+
it "should have a delimiter" do
|
33
|
+
subject.new("a name", delimiter: "!").delimiter.should == "!"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have a default delimiter" do
|
37
|
+
subject.new("a name", {}).delimiter.should == ";"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO this spec feels messy, refactor it!
|
42
|
+
it "should calculate a md5_hash from the source file" do
|
43
|
+
file = "/foo/bar/fixture.csv"
|
44
|
+
File.should_receive(:exist?).with(file).and_return(true)
|
45
|
+
|
46
|
+
file_fixture = subject.new("blub", source: file)
|
47
|
+
|
48
|
+
md5_file_double = double()
|
49
|
+
md5_file_double.should_receive(:hexdigest).and_return("md5")
|
50
|
+
::Digest::MD5.should_receive(:file).with(file).and_return(md5_file_double)
|
51
|
+
|
52
|
+
file_fixture.md5_hash.should == "md5"
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO this spec feels messy, refactor it!
|
56
|
+
it "#as_json" do
|
57
|
+
file = "/foo/bar/fixture.csv"
|
58
|
+
file_fixture = subject.new("blub", source: file)
|
59
|
+
file_fixture.should_receive(:md5_hash).and_return("md5_hash")
|
60
|
+
|
61
|
+
json = file_fixture.as_json
|
62
|
+
|
63
|
+
json[:source] = File.basename(file)
|
64
|
+
json[:md5_hash] = "md5"
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#next" do
|
68
|
+
context "no fields given" do
|
69
|
+
it "should return a marker and start with a sequence number of 1" do
|
70
|
+
subject.new("requests", {}).next.should == "${FILEFIXTURE|n=requests-seq=1}"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should increment the sequence on each call to #next" do
|
74
|
+
users = subject.new("users", {})
|
75
|
+
users.next.should == "${FILEFIXTURE|n=users-seq=1}"
|
76
|
+
users.next.should == "${FILEFIXTURE|n=users-seq=2}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "fields given" do
|
81
|
+
it "should increment the sequence on each call to #next" do
|
82
|
+
users = subject.new("users", fields: [:id, :email, :password])
|
83
|
+
users.next.email.should == "${FILEFIXTURE|f=email-n=users-seq=1}"
|
84
|
+
users.next.id.should == "${FILEFIXTURE|f=id-n=users-seq=2}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should raise NoMethodError on proxy when invalid field is given" do
|
89
|
+
users = subject.new("users", fields: [:id, :email, :password])
|
90
|
+
expect { users.next.i_do_not_exist}.to raise_error(NoMethodError)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should be a good ruby citizen and implement respond_to_missing" do
|
94
|
+
users = subject.new("users", fields: [:id, :email, :password])
|
95
|
+
# users.next.send(:respond_to_missing?, :foo).should == false
|
96
|
+
users.next.send(:respond_to_missing?, :id).should == true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StormForge::Dsl::TestCase::DataSource::RandomNumber do
|
4
|
+
subject { StormForge::Dsl::TestCase::DataSource::RandomNumber }
|
5
|
+
|
6
|
+
it "should return a marker and start with a sequence number of 1" do
|
7
|
+
subject.new("number", range: 1..10).next.should == "${GENERATOR|t=random_number-n=number-seq=1}"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should increment the sequence on each call to #next" do
|
11
|
+
foo = subject.new("another_number", range: 23..42)
|
12
|
+
foo.next.should == "${GENERATOR|t=random_number-n=another_number-seq=1}"
|
13
|
+
foo.next.should == "${GENERATOR|t=random_number-n=another_number-seq=2}"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should know how often #next was called" do
|
17
|
+
ref_token = subject.new("ref_token", range: 10..42)
|
18
|
+
2.times { ref_token.next }
|
19
|
+
ref_token.count.should == 2
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should work with an array for range too" do
|
23
|
+
subject.new("number", range: [23, 42]).range.should == (23..42)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "Invalid range options" do
|
27
|
+
it "should not accept missing range" do
|
28
|
+
expect {
|
29
|
+
subject.new("numer_without_range", range: nil)
|
30
|
+
}.to raise_error(StormForge::Dsl::TestCase::DataSource::RandomNumber::InvalidRange)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not accept non-numerical range" do
|
34
|
+
expect {
|
35
|
+
subject.new("numer_with_invalid", range: "a".."z")
|
36
|
+
}.to raise_error(StormForge::Dsl::TestCase::DataSource::RandomNumber::InvalidRange)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not accept range beginning below 0" do
|
40
|
+
expect {
|
41
|
+
subject.new("numer_with_invalid_range", range: -1..10)
|
42
|
+
}.to raise_error(StormForge::Dsl::TestCase::DataSource::RandomNumber::InvalidRange)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not accept range beginning over 100_000_000" do
|
46
|
+
expect {
|
47
|
+
subject.new("numer_with_invalid_range", range: 1..100_000_001)
|
48
|
+
}.to raise_error(StormForge::Dsl::TestCase::DataSource::RandomNumber::InvalidRange)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StormForge::Dsl::TestCase::DataSource::RandomString do
|
4
|
+
subject { StormForge::Dsl::TestCase::DataSource::RandomString }
|
5
|
+
|
6
|
+
it "should return a marker and start with a sequence number of 1" do
|
7
|
+
subject.new("ref_token", length: 10).next.should == "${GENERATOR|t=random_string-n=ref_token-seq=1}"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should increment the sequence for every invocation of #next" do
|
11
|
+
ref_token = subject.new("ref_token", length: 10)
|
12
|
+
ref_token.next.should == "${GENERATOR|t=random_string-n=ref_token-seq=1}"
|
13
|
+
ref_token.next.should == "${GENERATOR|t=random_string-n=ref_token-seq=2}"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should know how often #next was called" do
|
17
|
+
ref_token = subject.new("ref_token", length: 10)
|
18
|
+
2.times { ref_token.next }
|
19
|
+
ref_token.count.should == 2
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should default to length of 1" do
|
23
|
+
subject.new("token_length_1", {}).length.should == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should limit the length to 100" do
|
27
|
+
subject.new("long_token", length: 101).length.should == 100
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should ensure that length is a number" do
|
31
|
+
subject.new("ref_token", length: "meh").length.should == 1
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StormForge::Dsl::TestCase::Definition do
|
4
|
+
|
5
|
+
describe "Validations" do
|
6
|
+
|
7
|
+
subject { StormForge::Dsl::TestCase::Definition.new :slug, Proc.new {} }
|
8
|
+
before(:each) { subject.valid? }
|
9
|
+
|
10
|
+
it "requires a title" do
|
11
|
+
subject.errors[:title].should be_present
|
12
|
+
end
|
13
|
+
|
14
|
+
it "requires a version" do
|
15
|
+
subject.errors[:version].should be_present
|
16
|
+
end
|
17
|
+
|
18
|
+
it "requires at least one target" do
|
19
|
+
subject.errors[:targets].should be_present
|
20
|
+
test_case = StormForge::Dsl::TestCase::Definition.new :slug do
|
21
|
+
targets "target1"
|
22
|
+
end
|
23
|
+
test_case.valid?
|
24
|
+
test_case.errors[:targets].should be_empty
|
25
|
+
end
|
26
|
+
|
27
|
+
it "requires at least one arrival phase" do
|
28
|
+
subject.errors[:arrival_phases].should be_present
|
29
|
+
end
|
30
|
+
|
31
|
+
it "requires at least one session" do
|
32
|
+
subject.errors[:sessions].should be_present
|
33
|
+
end
|
34
|
+
|
35
|
+
it "requires to have a total session probability of 100%" do
|
36
|
+
test_case = StormForge::Dsl::TestCase::Definition.new :slug do
|
37
|
+
session "a", 10, Proc.new {}
|
38
|
+
end
|
39
|
+
test_case.valid?
|
40
|
+
test_case.errors[:sessions].should be_present
|
41
|
+
|
42
|
+
test_case = StormForge::Dsl::TestCase::Definition.new :slug do
|
43
|
+
session "a", 100, Proc.new {}
|
44
|
+
end
|
45
|
+
test_case.valid?
|
46
|
+
test_case.errors[:sessions].should be_empty
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have a description" do
|
52
|
+
test_case = StormForge::Dsl::TestCase::Definition.new :slug do
|
53
|
+
description "test case description"
|
54
|
+
end
|
55
|
+
|
56
|
+
test_case.description.should == "test case description"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have cloud configuration" do
|
60
|
+
expect {
|
61
|
+
StormForge::Dsl::TestCase::Definition.new :slug do
|
62
|
+
self.respond_to?(:cloud).should == true
|
63
|
+
cloud :provider, Proc.new {}
|
64
|
+
end
|
65
|
+
}.not_to raise_error
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should serialize to JSON" do
|
69
|
+
test_case = StormForge::Dsl::TestCase::Definition.new :my_1st_case_title do
|
70
|
+
title "my 1st case title"
|
71
|
+
version "version"
|
72
|
+
targets "a1"
|
73
|
+
arrival_phase duration: 1.hour, rate: 100.per_second
|
74
|
+
session "GET /", 100.percent, Proc.new {}
|
75
|
+
end
|
76
|
+
|
77
|
+
# do a sanity check, to verify that the test_case is valid
|
78
|
+
test_case.valid?
|
79
|
+
test_case.errors.should be_empty
|
80
|
+
|
81
|
+
test_case.to_json(root: false).should match_json_expression({
|
82
|
+
dsl_version: :v1,
|
83
|
+
slug: "my_1st_case_title",
|
84
|
+
title: "my 1st case title",
|
85
|
+
version: "version",
|
86
|
+
targets: ["a1"],
|
87
|
+
arrival_phases: [
|
88
|
+
{
|
89
|
+
warmup: false,
|
90
|
+
duration: 3600,
|
91
|
+
duration_unit: :second,
|
92
|
+
rate: 100.0,
|
93
|
+
rate_unit: :second
|
94
|
+
}
|
95
|
+
].ordered!,
|
96
|
+
data_sources: nil,
|
97
|
+
sessions: {
|
98
|
+
"GET /" => {
|
99
|
+
name: "GET /",
|
100
|
+
probability: 100,
|
101
|
+
steps: [],
|
102
|
+
data_sources_usage: {}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
})
|
106
|
+
end
|
107
|
+
end
|