Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6 support and tests improvements #33

Merged
merged 8 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions share/api.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
openapi: "3.0.0"
info:
version: "0.10.0"
version: "0.10.1"
title: "Provisioning Engine REST API"
description: Provides FaaS capabilities by leveraging features from OpenNebula. Allows to manage Serverless Runtime instances based on a group of Functions defined on request.

Expand Down Expand Up @@ -28,7 +28,7 @@ paths:
security: []
responses:
'200':
description: Serverless Runtime schema retrieved
description: Returns the serverless runtime schema
/serverless-runtimes:
post:
summary: Create a Serverless Runtime
Expand Down Expand Up @@ -206,7 +206,7 @@ paths:
schema:
type: string
example:
"0.10.0"
"0.10.1"
/server/config:
get:
summary: Retrieve the Provisioning Engine configuration
Expand Down
13 changes: 12 additions & 1 deletion src/server/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ def service_delete(id)
end

def service_destroy(id)
service_recover(id, { 'delete' => true })
response = service_recover(id, { 'delete' => true })
return response if response[0] == 204

# attempt a second recover
@logger.error response[1]
sleep 1
return service_recover(id, { 'delete' => true })
end

def service_recover(id, options = {})
Expand All @@ -109,6 +115,11 @@ def service_state(service)
service['DOCUMENT']['TEMPLATE']['BODY']['state']
end

def service_pool_get
response = @client_oneflow.get('/service')
return_http_response(response)
end

def service_template_get(id)
response = @client_oneflow.get("/service_template/#{id}")
return_http_response(response)
Expand Down
2 changes: 1 addition & 1 deletion src/server/log.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Logger
:error => :err, :warning => :warning, :info => :info, :debug => :debug
}
}
SEP = '-----------------------'
SEP = '-'*32

#
# @param [Hash] config Log configuration as defined in engine.conf
Expand Down
19 changes: 10 additions & 9 deletions src/server/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ def self.create(client, specification)
response = ServerlessRuntime.to_service(client, specification)
return response unless response[0] == 200

client.logger.debug_dev(response)

service_id = response[1]['DOCUMENT']['ID'].to_i
specification['SERVICE_ID'] = service_id

Expand Down Expand Up @@ -142,7 +140,7 @@ def delete

@cclient.logger.warning(SRS_NOT_FOUND) if rc == 404

if rc != 204
if ![204, 404].include?(rc)
error = "#{SERVICE_NO_DELETE} #{service_id}"
message = response[1]

Expand Down Expand Up @@ -484,20 +482,23 @@ def self.xaas_template(client, role)
xaas_template['VM_ID'] = vm_id
xaas_template['STATE'] = map_vm_state(vm)

if xaas_template['STATE'] == FUNCTION_STATES[3] # error
# TODO: Test
if xaas_template['STATE'] == 'ERROR'
if vm["#{t}ERROR"]
xaas_template['ERROR'] = vm["#{t}ERROR"]
else
xaas_template['ERROR'] = 'No VM Error from Cloud Edge Manager'
end
end

if vm["#{nic}EXTERNAL_IP"]
xaas_template['ENDPOINT'] = vm["#{nic}EXTERNAL_IP"]
else
xaas_template['ENDPOINT'] = vm["#{nic}IP"]
if nic
['EXTERNAL_IP', 'IP6', 'IP'].each do |address| # Priority order
if vm["#{nic}#{address}"]
xaas_template['ENDPOINT'] = vm["#{nic}#{address}"]
break
end
end
end
# No ENDPOINT will result in empty string
xaas_template['ENDPOINT'] = '' unless xaas_template['ENDPOINT']

xaas_template['CPU'] = vm["#{t}VCPU"].to_i
Expand Down
8 changes: 2 additions & 6 deletions src/server/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
require 'error'
require 'runtime'

VERSION = '0.10.0'
VERSION = '0.10.1'

############################################################################
# Define API Helpers
Expand Down Expand Up @@ -127,7 +127,7 @@ def log_response(level, code, data, message)
end

get '/serverless-runtimes/schema' do
json_response(200, ProvisionEngine::ServerlessRuntime::SCHEMA_SPECIFICATION)
json_response(200, ProvisionEngine::ServerlessRuntime::SCHEMA)
end

post '/serverless-runtimes' do
Expand Down Expand Up @@ -266,10 +266,6 @@ def log_response(level, code, data, message)
end
end

get '/engine/version' do
json_response(200, VERSION)
end

get '/server/version' do
json_response(200, VERSION)
end
Expand Down
12 changes: 6 additions & 6 deletions tests/conf.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# How long to wait for the operation expected result before raising timeout error
:timeouts:
:timeouts: # How long to wait for the operation expected result before raising timeout error
:get: 60
:delete: 30
# What group of examples should be tested
:examples:
'auth': true
:examples: # What group of examples should be tested
'crud': true
'auth': true
'crud_invalid': true
'inspect logs': true
'server_info': true
'logs': true
:purge: true # delete services owned by the user running the tests. DO NOT RUN AS ONEADMIN !!!
62 changes: 45 additions & 17 deletions tests/init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@
require 'opennebula/oneflow_client'

# Engine libraries
$LOAD_PATH << "#{__dir__}/../src/server"
require 'runtime'
require 'error'
require_relative '../src/client/client'
require_relative '../src/server/runtime'
require_relative '../src/server/error'

$LOAD_PATH << "#{__dir__}/lib" # Test libraries
require 'common'
require 'log'
require 'crud'
require 'auth'
require 'crud_invalid'

############################################################################
# Initialize rspec configuration
Expand All @@ -39,7 +36,10 @@
}

rspec_conf = {
:conf => YAML.load_file('./conf.yaml'),
:conf => {
:tests => YAML.load_file('./conf.yaml'),
:engine => conf_engine
},
:client => {
:engine => ProvisionEngine::Client.new(endpoint, auth),
:oned => OpenNebula::Client.new(auth, conf_engine[:one_xmlrpc]),
Expand All @@ -55,22 +55,50 @@
############################################################################
RSpec.describe 'Provision Engine API' do
include Rack::Test::Methods
tests = rspec_conf[:conf][:tests][:examples]

examples?('auth', rspec_conf[:conf])
examples?('crud_invalid', rspec_conf[:conf])
if tests['crud']
require 'crud'

# test every serverless runtime template under templates directory
Dir.entries("#{__dir__}/templates").select do |sr_template|
# blacklist template from tests by changing preffix or suffix
next unless sr_template.start_with?('sr_') && sr_template.end_with?('.json')
# test every serverless runtime template under templates directory
Dir.entries("#{__dir__}/templates").select do |sr_template|
# blacklist template from tests by changing preffix or suffix
next unless sr_template.start_with?('sr_') && sr_template.end_with?('.json')

examples?('crud', rspec_conf[:conf], sr_template)
include_context('crud', sr_template)
end
end

examples?('inspect logs', rspec_conf[:conf])
tests.each do |examples, enabled|
next if examples == 'crud'

if enabled
require examples
include_context(examples)
end
end

# cleanup possible leftover services for the test user ENV['TESTS_AUTH'][0]
after(:all) do
# TODO: Skip if oneadmin
if rspec_conf[:conf][:tests][:purge]
require 'client'
require 'log'
require 'logger'

client = ProvisionEngine::CloudClient.new(conf_engine, auth)
response = client.service_pool_get
expect(response[0]).to eq(200)

document_pool = response[1]['DOCUMENT_POOL']
if !document_pool.empty?
pp "Found leftover services as the user #{auth.split(':')[0]}"

document_pool['DOCUMENT'].each do |service|
pp "#{service['ID']}: #{service['NAME']}"

response = client.service_destroy(service['ID'])
expect([204, 404].include?(response[0])).to be(true)
end
end
end
end
end
28 changes: 20 additions & 8 deletions tests/lib/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# RSpec methods
############################################################################

def examples?(examples, conf, params = nil)
def load_examples(params = nil)
include_context(examples, params) if conf[:examples][examples]
end

Expand All @@ -30,12 +30,16 @@ def verify_sr_spec(specification, runtime)
response = @conf[:client][:oneflow].get("/service/#{runtime['SERVICE_ID']}")
expect(response.code.to_i).to eq(200)

t = '//TEMPLATE/'

['FAAS', 'DAAS'].each do |role|
next unless specification[role] && !specification[role]['FLAVOUR'].empty?

vm = OpenNebula::VirtualMachine.new_with_id(runtime[role]['VM_ID'], @conf[:client][:oned])
raise "Error getting #{SR} VM" if OpenNebula.is_error?(vm.info)

nic = "#{t}NIC[NIC_ID=\"0\"]/"

# mandatory role information exists
['FLAVOUR', 'VM_ID', 'STATE', 'ENDPOINT'].each do |mandatory|
expect(runtime[role].key?(mandatory)).to be(true)
Expand All @@ -48,20 +52,28 @@ def verify_sr_spec(specification, runtime)
expect(runtime[role][optional]).to eq(specification[role][optional])
end

# rubocop:disable Style/StringLiterals
# verify VM has correct resources
['CPU', 'VCPU', 'MEMORY'].each do |capacity|
next unless specification[role][capacity]

expect(vm["//TEMPLATE/#{capacity}"].to_f).to eq(specification[role][capacity].to_f)
expect(vm["#{t}#{capacity}"].to_f).to eq(specification[role][capacity].to_f)
end

expect(runtime[role]['ENDPOINT']).to eq(vm["//TEMPLATE/NIC[NIC_ID=\"0\"]/IP"].to_s)
['EXTERNAL_IP', 'IP6', 'IP'].each do |address|
if vm["#{nic}#{address}"]
expect(runtime[role]['ENDPOINT']).to eq(vm["#{nic}#{address}"])
break
end
end

if specification[role]['DISK_SIZE']
expect(vm["//TEMPLATE/DISK[DISK_ID=\"0\"]/SIZE"].to_i).to eq(specification[role]['DISK_SIZE'])
expect(vm["#{t}DISK[DISK_ID=\"0\"]/SIZE"].to_i).to eq(specification[role]['DISK_SIZE'])
end

if vm["#{t}ERROR"]
expect(runtime[role]['STATE']).to eq('ERROR')
expect(runtime[role]['ERROR']).to eq(vm["#{t}ERROR"])
end
# rubocop:enable Style/StringLiterals
end
end

Expand All @@ -72,7 +84,7 @@ def verify_sr_delete(sr_id)
when 204
verify_service_delete(sr_id)
when 423
attempts = @conf[:conf][:timeouts][:get]
attempts = @conf[:conf][:tests][:timeouts][:get]
1.upto(attempts) do |t|
expect(t <= attempts).to be(true)
sleep 1
Expand All @@ -99,7 +111,7 @@ def verify_sr_delete(sr_id)
end

def verify_service_delete(sr_id)
attempts = @conf[:conf][:timeouts][:delete]
attempts = @conf[:conf][:tests][:timeouts][:delete]
1.upto(attempts) do |t|
expect(t <= attempts).to be(true)
sleep 1
Expand Down
25 changes: 4 additions & 21 deletions tests/lib/crud.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,12 @@
it "read a #{SR}" do
skip "#{SR} creation failed" unless @conf[:create]

attempts = @conf[:conf][:timeouts][:get]
response = @conf[:client][:engine].get(@conf[:id])
expect(response.code).to eq(200)

1.upto(attempts) do |t|
expect(t <= attempts).to be(true)
sleep 1

response = @conf[:client][:engine].get(@conf[:id])

expect(response.code).to eq(200)

runtime = JSON.parse(response.body)
pp runtime
runtime = JSON.parse(response.body)

case runtime['SERVERLESS_RUNTIME']['FAAS']['STATE']
when ProvisionEngine::ServerlessRuntime::FUNCTION_STATES[1]
verify_sr_spec(@conf[:specification], runtime)
break
when ProvisionEngine::ServerlessRuntime::FUNCTION_STATES[3]
raise 'FaaS VM failed to deploy'
else
next
end
end
verify_sr_spec(@conf[:specification], runtime)
end

it "fail to update #{SR}" do
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/log.rb → tests/lib/logs.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
RSpec.shared_context 'inspect logs' do
RSpec.shared_context 'logs' do
it 'print every log' do
logcation = '/var/log/provision-engine'
sep = '-'*32
Expand Down
Loading