Class: XXabbrevupperxxHelper

Inherits:
Object
  • Object
show all
Includes:
Test::Unit::Assertions
Defined in:
lib/taft_files/framework/zznamezz/api_helpers/rest.rb,
lib/taft_files/framework/zznamezz/api_helpers/general.rb,
lib/taft_files/framework/zznamezz/ui_helpers/ui_general.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object

E.g. calling homepage.displayed? from a test script : Test cannot see homepage so its call is routed through method_missing If method_missing returns an instance of the class, .displayed? can be called on it (seamlessly) At present this will happen for every call to a page from a test script



18
19
20
21
22
23
24
25
26
27
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 18

def method_missing(name, *args, &block)
    #puts "XXabbrevupperxxHelper method_missing called; name = #{name.inspect}; #{name.class}"
 
    case name.to_s
    when /^xxabbrevxx/i
        RSPages.find(name.to_s) # return the page so that the helper can use it
    else
        super
    end
end

Instance Method Details

#additional_encoding(s) ⇒ Object

Method to perform additional encoding URI.encode does not convert the following chars: : +



108
109
110
111
112
113
114
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 108

def additional_encoding(s)
    encoding_hash = {":" => "%3A", "+" => "%2B"}
    encoding_hash.each_pair do |k, v|
        s.gsub!(k, v)
    end
    s
end

#chmod_linux_file(host, user, pass, path, file_name) ⇒ Object

Sets 777 permissions to the Linux server file Need the file name & dir



114
115
116
117
118
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 114

def chmod_linux_file(host, user, pass, path, file_name)
    Net::SSH.start(host, user, :password => pass) do |ssh|
        ssh.exec!("cd #{path}; chmod 777 #{file_name}")
    end
end

#create_tar_gz_file(gz_base_file_name, source_file) ⇒ Object

Forms a .tar.gz archive from the specified source file Creates the file in the working directory Creates the .tar.gz via a call to system



90
91
92
93
94
95
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 90

def create_tar_gz_file(gz_base_file_name, source_file)
    gz_name = "#{gz_base_file_name}.tar.gz"
    cmd = "tar -czf #{gz_name} #{source_file}"
    system(cmd)
    gz_name
end

#delete_request(client) ⇒ Object

Method to perform a DELETE request. Requires the RESTClient Resource client. Returns a RESTClient::Response object



235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 235

def delete_request(client)
    begin
        client.delete
    rescue OpenSSL::SSL::SSLError => e
        raise "SSLError occurred when calling REST service; #{e}"
    rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
        puts "RestClient::Exception hit when calling REST service"
        puts e
        puts e.response
        return e.response
    rescue => e
        raise "Unexpected error occurred when calling REST service; #{e}"
    end
end

#encode_uri(uri) ⇒ Object

Method to encode the URI Takes a string or an array of path fragments. If an array, the contents will be joined using / characters



100
101
102
103
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 100

def encode_uri(uri)
    uri = uri.join("/") if uri.class == Array
    additional_encoding(URI.parse(URI.encode(uri)).to_s)
end

#get_response_body(response) ⇒ Object

Converts the body of the response object from JSON to Ruby, and sets the defaults for the main hash and all sub-hashes



122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 122

def get_response_body(response)
    raise "REST response was nil" if response == nil
    raise "REST response had no attached body" if response.body == nil
    begin
        body = JSON.parse(response.body, {:max_nesting => 100})
        set_all_defaults(body)
    rescue JSON::ParserError => e
        puts "rescued : ParserError"
        puts e
        body = response.body
    end
    body
end

#get_response_header(response) ⇒ Object

Converts the header of the response object from JSON to Ruby, and sets the defaults for the main hash and all sub-hashes



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 138

def get_response_header(response)
    raise "REST response was nil" if response == nil
    raise "REST response had no attached header" if response.headers == nil
    begin
        header = response.headers # already in Ruby Hash format
        set_all_defaults(body)
    rescue JSON::ParserError => e
        puts "rescued : ParserError"
        puts e
        header = response.headers
    end
    header
end

#get_rest_client(service, cert_symbol = :regular, parameter_array_or_hash = [], base_url = , version = nil, timeout = 150) ⇒ Object

Returns a RestClient::Resource object pointing to the URL of the requested service



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 12

def get_rest_client(service, cert_symbol = :regular, parameter_array_or_hash = [], base_url = ZZnamezzConfig::SERVER[:zznamezz_url], version = nil, timeout = 150)
    
    separator = "/"
    api_version_string = separator + ZZnamezzConfig::API_VERSION.to_s # as the version parameter can be entirely absent, let's build the separator into the term
    api_version_string = "" if ZZnamezzConfig::API_VERSION == :none # special case

    api_version_string = separator + version if version # override always wins

    parameter_array_or_hash = [parameter_array_or_hash] if parameter_array_or_hash.class != Array && parameter_array_or_hash.class != Hash # convert to array if a non-array/hash was supplied
    
    # If common headers are needed
    # headers = {"foo" => bar}

    # Build up the path-string, then append it to the base URL
    s = "" # initialise before manipulating it

    if service.class == String
        s = service
    else
        case service
        when :options
            s = "options#{api_version_string}"
            s += "/#{parameter_array_or_hash[0]}"
        when :build_number
            s = "query/info#{api_version_string}/buildnumber"
        else
            raise "Unknown service #{service} supplied to #{__method__}"
        end
    end

    encoded = encode_uri(s).to_s # Generates a URI::Generic object; we want a string
    url = base_url + encoded

    puts url

    #######################################################
    # Get certificate and other parameters needed for valid credentials
    #######################################################

    OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] = "SSLv3" # this may or may not be needed

    cert_path = File.expand_path(ZZnamezzConfig::CERTIFICATE_DIR) # this must be an absolute filepath
    cert_extension = get_user_cert_ext(cert_symbol).to_s

    cert_name = get_user_p12_cert_name(cert_symbol)
    cert_pw = get_user_cert_pw(cert_symbol)

    # ca_file = ZZnamezzConfig::CA_CERTIFICATE_FILE # needed for VERIFY_PEER mode # VERIFY_PEER mode currently disabled

    if cert_extension.to_sym == :pem
        # If PEM, the credentials are in two parts - the certs.pem file and the key.pem file
        # Need to read in the two separate files & construct OpenSSL::X509::Certificate & OpenSSL::PKey::RSA objects
        cert_key_name = get_user_pem_cert_key_name(cert_symbol)
        cert_key_pw = get_user_cert_key_pw(cert_symbol)
        pem = File.read(File.join(cert_path, cert_name))
        key_pem = File.read(File.join(cert_path, cert_key_name))

        cert = OpenSSL::X509::Certificate.new(pem)

        begin
            key = OpenSSL::PKey::RSA.new(key_pem, cert_key_pw)
        rescue
            raise "Could not form OpenSSL::PKey::RSA object for the corresponding key.pem file. Does it have the right password?"
        end
        return RestClient::Resource.new(url, {:ssl_client_cert => cert, :ssl_client_key => key, :verify_ssl => OpenSSL::SSL::VERIFY_NONE, :timeout => timeout})
    else
        # If P12 or PFX, only need to construct the one object - the certificate and key are both stored within it
        begin
            p12 = OpenSSL::PKCS12.new(File.read(File.join(cert_path, cert_name), :binmode => true), cert_pw)
        rescue OpenSSL::PKCS12::PKCS12Error => e
            if e.to_s.include?("mac verify failure")
                raise "Could not create PKCS12 object from certificate #{cert_name}; please specify a password for the certificate"
            else
                raise e
            end
        end

        # Use if performing SSL Peer verification - needs a ca certificate
        return RestClient::Resource.new(url, {:ssl_client_cert => p12.certificate, :ssl_client_key => p12.key, :ssl_ca_file => ca_file, :verify_ssl => OpenSSL::SSL::VERIFY_PEER, :headers => headers, :timeout => timeout})

        # Use if not performing SSL Peer verification - does not need a ca certificate
        return RestClient::Resource.new(url, {:ssl_client_cert => p12.certificate, :ssl_client_key => p12.key, :verify_ssl => OpenSSL::SSL::VERIFY_NONE, :timeout => timeout})
    end

end

#get_version_number_from_api(cert_symbol = :regular) ⇒ Object

Calls the build_number REST method This is an example of how to use get_rest_client



80
81
82
83
84
85
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 80

def get_version_number_from_api(cert_symbol = :regular)
    client = get_rest_client(:build_number, cert_symbol)
    json = client.get # {"message":"1.8.0"}
    parsed = JSON.parse(json)
    parsed["message"]
end

#new_browser_at_url(url) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/taft_files/framework/zznamezz/ui_helpers/ui_general.rb', line 4

def new_browser_at_url(url)
    puts "New browser at #{url}"
    case ZZnamezzConfig::BROWSER
    when :chrome
        # Set detach to true so the browser remains open once the test finishes
        options = Selenium::WebDriver::Chrome::Options.new
        options.add_option(:detach, true)
        b = Watir::Browser.new :chrome, :options => options

    when :firefox
        b = Watir::Browser.new :firefox

    end

    b.goto url

    # Store the new browser in the global list
    $browsers << b

    b # return the browser
end

#post_file_request(client, post_information_hash, additional_hash = nil) ⇒ Object

Method to perform a POST request that sends a file. Requires the RESTClient Resource client and a hash of the information to be sent in the POST body. Assumes that all file information (including the File object itself) is included in the supplied hash Optionally also takes an additional hash which contains desired headers for the POST request. Returns a RESTClient::Response object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 190

def post_file_request(client, , additional_hash = nil)
    new_hash = {}
    additional_hash ||= {} 
    new_hash.merge!(additional_hash)

    begin
        client.post(, new_hash)
    rescue OpenSSL::SSL::SSLError => e
        raise "SSLError occurred when calling REST service; #{e}"
    rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
        puts "RestClient::Exception hit when calling REST service"
        puts e
        puts e.response
        return e.response
    rescue => e
        raise "Unexpected error occurred when calling REST service; #{e}"
    end
end

#post_request(client, post_information_hash, additional_hash = nil) ⇒ Object

Method to perform a POST request. Requires the RESTClient Resource client and a hash of the information to be sent in the POST body. This hash is converted to JSON for the POST. Optionally also takes an additional hash which contains desired headers for the POST request. Returns a RESTClient::Response object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 167

def post_request(client, , additional_hash = nil)
    new_hash = {:content_type => "application/json"}
    additional_hash ||= {} 
    new_hash.merge!(additional_hash)

    begin
        client.post(JSON.generate(, {:max_nesting => 100}), new_hash)
    rescue OpenSSL::SSL::SSLError => e
        raise "SSLError occurred when calling REST service; #{e}"
    rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
        puts "RestClient::Exception hit when calling REST service"
        puts e
        puts e.response
        return e.response
    rescue => e
        raise "Unexpected error occurred when calling REST service; #{e}"
    end
end

#put_request(client, put_information_hash, additional_hash = nil) ⇒ Object

Method to perform a PUT request. Requires the RESTClient Resource client and a hash of the information to be sent in the PUT body. This hash is converted to JSON for the PUT. Optionally also takes an additional hash which contains desired headers for the PUT request, e.g. => “application/json” Returns a RESTClient::Response object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 213

def put_request(client, put_information_hash, additional_hash = nil)
    new_hash = {:content_type => "application/json"}
    additional_hash ||= {} 
    new_hash.merge!(additional_hash)

    begin
        client.put(JSON.generate(put_information_hash, {:max_nesting => 100}), new_hash)
    rescue OpenSSL::SSL::SSLError => e
        raise "SSLError occurred when calling REST service; #{e}"
    rescue RestClient::Exception => e # if the request failed, RestClient will throw an error. We want to retrieve that error and the response within
        puts "RestClient::Exception hit when calling REST service"
        puts e
        puts e.response
        return e.response
    rescue => e
        raise "Unexpected error occurred when calling REST service; #{e}"
    end
end

#read_avro_file(filename) ⇒ Object

Reads in a serialised AVRO file Returns an array of the deserialised data rows



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 57

def read_avro_file(filename)
    lines = []
    File.open(path, "rb") do |f|
        reader = Avro::IO::DatumReader.new
        dr = Avro::DataFile::Reader.new(f, reader)
        dr.each do |record|
            lines << record
        end
    end
    lines
end

#read_csv_data_from_file(full_file_path) ⇒ Object

Reads in a CSV



36
37
38
39
40
41
42
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 36

def read_csv_data_from_file(full_file_path)
    data = []
    CSV.open(full_file_path, "r") do |csv|
        data = csv.readlines
    end
    data
end

#read_csv_test_data(filename) ⇒ Object

Reads in a file of CSV test data, e.g for use in data-driven tests



30
31
32
33
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 30

def read_csv_test_data(filename)
    path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../tests/data", filename)
    read_csv_data_from_file(path)
end

#read_epoch_time(microseconds_since_epoch) ⇒ Object

Converts a string or int representing the number of microseconds since the Time epoch (1970/01/01) into a DateTime object



117
118
119
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 117

def read_epoch_time(microseconds_since_epoch)
    Time.at(microseconds_since_epoch.to_i/1000)
end

#read_json_schema(schema_filename) ⇒ Object

Reads in a JSON schema



45
46
47
48
49
50
51
52
53
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 45

def read_json_schema(schema_filename)
    path = File.join(File.dirname(File.expand_path(__FILE__)) + "/../../../tests/data", schema_filename)
    data = []
    File.open(path, "r") do |f|
        data = f.readlines
    end
    schema = JSON.parse(data.chomp) # there may be trailing whitespace
    schema
end

#rename_linux_file(old_file, new_file, cert_symbol = :regular) ⇒ Object

Renames the specified file on the Linux server Needs the full path



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 99

def rename_linux_file(old_file, new_file, cert_symbol = :regular)
    # Derive the FTP host & path from the URL in config
    host = ZZnamezzConfig::SERVER[:zznamezz_url].split("//")[1].split(":")[0]
    host_short_form = host.split(".")[0]
    user = get_user_id(cert_symbol)
    pass = get_user_cert_pw(cert_symbol)

    Net::SFTP.start(host, user, :password => pass) do |sftp|
        puts "Renaming file : #{old_file} -> #{new_file}"
        sftp.rename(old_file, new_file)
    end
end

#set_all_defaults(hash, default = nil) ⇒ Object

Takes a hash a recursively sets the default of the hash and all sub-hashes



153
154
155
156
157
158
159
160
161
162
# File 'lib/taft_files/framework/zznamezz/api_helpers/rest.rb', line 153

def set_all_defaults(hash, default = nil)
    return unless hash.class == Hash
    hash.default = default
    hash.each_pair do |k, v|
        set_all_defaults(v) if v.class == Hash
        if v.class == Array
            v.each {|z| set_all_defaults(z) if z.class == Hash}
        end
    end
end

#submit_curl_command(cmd, cert_symbol = :regular) ⇒ Object

Executes the supplied curl command on the server



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 121

def submit_curl_command(cmd, cert_symbol = :regular)
    # Derive the FTP host & path from the URL in config
    host = ZZnamezzConfig::SERVER[:zznamezz_url].split("//")[1].split(":")[0]
    host_short_form = host.split(".")[0]
    user = get_user_id(cert_symbol)
    pass = get_user_cert_pw(cert_symbol)

    output = ""
    Net::SSH.start(host, user, :password => pass) do |ssh|
        output = ssh.exec!(cmd)
    end

    # We expect a JSON response from the server
    # The recorded output will contain this inside curl's own SDTOUT, so we need to extract the JSON
    output = output[output.index("{") .. output.index("}")]
    JSON.parse(output)
end

#validate_hash_against_json_schema(hash, schema_filename) ⇒ Object

Validates the supplied hash against the JSON schema



70
71
72
73
74
75
76
# File 'lib/taft_files/framework/zznamezz/api_helpers/general.rb', line 70

def validate_hash_against_json_schema(hash, schema_filename)
    raise "Must supply a hash to #{__method__}" unless hash.class == Hash

    schema = read_json_schema(schema_filename)
    errors = JSON::Validator.fully_validate(schema, hash)
    errors
end