stormforge-ruby 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|