From ae0c226aa324f8b3c64c13bf2989f8fbdab5d7ed Mon Sep 17 00:00:00 2001 From: Alberto Gutierrez Date: Tue, 24 Oct 2017 21:53:12 +0200 Subject: [PATCH] Migration after rename models --- .../consumption/consumption_manager.rb | 12 +- .../manageiq/consumption/showback_charge.rb | 113 --------- ...wback_event.rb => showback_data_rollup.rb} | 82 +++---- .../cpu.rb | 2 +- .../disk.rb | 2 +- .../fixed.rb | 2 +- .../flavor.rb | 2 +- .../mem.rb | 2 +- .../metering.rb | 2 +- .../net.rb | 2 +- .../storage.rb | 2 +- .../consumption/showback_data_view.rb | 117 +++++++++ ...{showback_pool.rb => showback_envelope.rb} | 90 +++---- .../consumption/showback_input_measure.rb | 33 +++ .../consumption/showback_price_plan.rb | 12 +- .../manageiq/consumption/showback_rate.rb | 38 +-- .../manageiq/consumption/showback_tier.rb | 2 +- .../consumption/showback_usage_type.rb | 33 --- db/fixtures/showback_input_measures.yml | 116 +++++++++ db/fixtures/showback_usage_types.yml | 116 --------- ...wback_event.rb => showback_data_rollup.rb} | 2 +- ...owback_charge.rb => showback_data_view.rb} | 13 +- ...{showback_pool.rb => showback_envelope.rb} | 2 +- spec/factories/showback_input_measure.rb | 8 + spec/factories/showback_rate.rb | 22 +- spec/factories/showback_usage_type.rb | 8 - spec/models/consumption_manager_spec.rb | 38 +-- .../cpu_spec.rb | 14 +- .../flavor_spec.rb | 16 +- .../mem_spec.rb | 14 +- ...t_spec.rb => showback_data_rollup_spec.rb} | 225 +++++++++--------- ...rge_spec.rb => showback_data_view_spec.rb} | 86 +++---- ...pool_spec.rb => showback_envelope_spec.rb} | 130 +++++----- spec/models/showback_input_measure_spec.rb | 81 +++++++ spec/models/showback_price_plan_spec.rb | 24 +- spec/models/showback_rate_spec.rb | 168 ++++++------- spec/models/showback_tier_spec.rb | 2 +- spec/models/showback_usage_type_spec.rb | 81 ------- 38 files changed, 853 insertions(+), 861 deletions(-) delete mode 100644 app/models/manageiq/consumption/showback_charge.rb rename app/models/manageiq/consumption/{showback_event.rb => showback_data_rollup.rb} (57%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/cpu.rb (94%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/disk.rb (60%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/fixed.rb (71%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/flavor.rb (94%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/mem.rb (86%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/metering.rb (57%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/net.rb (60%) rename app/models/manageiq/consumption/{showback_event => showback_data_rollup}/storage.rb (71%) create mode 100644 app/models/manageiq/consumption/showback_data_view.rb rename app/models/manageiq/consumption/{showback_pool.rb => showback_envelope.rb} (51%) create mode 100644 app/models/manageiq/consumption/showback_input_measure.rb delete mode 100644 app/models/manageiq/consumption/showback_usage_type.rb create mode 100644 db/fixtures/showback_input_measures.yml delete mode 100644 db/fixtures/showback_usage_types.yml rename spec/factories/{showback_event.rb => showback_data_rollup.rb} (92%) rename spec/factories/{showback_charge.rb => showback_data_view.rb} (77%) rename spec/factories/{showback_pool.rb => showback_envelope.rb} (86%) create mode 100644 spec/factories/showback_input_measure.rb delete mode 100644 spec/factories/showback_usage_type.rb rename spec/models/{showback_event => showback_data_rollup}/cpu_spec.rb (89%) rename spec/models/{showback_event => showback_data_rollup}/flavor_spec.rb (94%) rename spec/models/{showback_event => showback_data_rollup}/mem_spec.rb (86%) rename spec/models/{showback_event_spec.rb => showback_data_rollup_spec.rb} (63%) rename spec/models/{showback_charge_spec.rb => showback_data_view_spec.rb} (70%) rename spec/models/{showback_pool_spec.rb => showback_envelope_spec.rb} (68%) create mode 100644 spec/models/showback_input_measure_spec.rb delete mode 100644 spec/models/showback_usage_type_spec.rb diff --git a/app/models/manageiq/consumption/consumption_manager.rb b/app/models/manageiq/consumption/consumption_manager.rb index 5c1e2d9..a1ca718 100644 --- a/app/models/manageiq/consumption/consumption_manager.rb +++ b/app/models/manageiq/consumption/consumption_manager.rb @@ -14,7 +14,7 @@ def self.description def self.update_events data_units = load_column_units generate_new_month unless Time.now.utc.strftime("%d").to_i != 1 - ManageIQ::Consumption::ShowbackEvent.events_actual_month.each do |event| + ManageIQ::Consumption::ShowbackDataRollup.events_actual_month.each do |event| event.update_event(data_units) event.save end @@ -25,9 +25,9 @@ def self.init_month end def self.generate_new_month - events = ManageIQ::Consumption::ShowbackEvent.events_past_month + events = ManageIQ::Consumption::ShowbackDataRollup.events_past_month events.each do |ev| - next if ManageIQ::Consumption::ShowbackEvent.where(["start_time >= ?", init_month]).exists?(:resource=> ev.resource) + next if ManageIQ::Consumption::ShowbackDataRollup.where(["start_time >= ?", init_month]).exists?(:resource=> ev.resource) generate_event_resource(ev.resource, DateTime.now.utc.beginning_of_month, load_column_units) end events @@ -38,14 +38,14 @@ def self.generate_new_month def self.generate_events RESOURCES_TYPES.each do |resource| resource.constantize.all.each do |one_resource| - next if ManageIQ::Consumption::ShowbackEvent.where(["start_time >= ?", init_month]).exists?(:resource => one_resource) + next if ManageIQ::Consumption::ShowbackDataRollup.where(["start_time >= ?", init_month]).exists?(:resource => one_resource) generate_event_resource(one_resource, DateTime.now.utc, load_column_units) end end end def self.generate_event_resource(resource, date, data_units) - e = ManageIQ::Consumption::ShowbackEvent.new( + e = ManageIQ::Consumption::ShowbackDataRollup.new( :resource => resource, :start_time => date, :end_time => date @@ -58,7 +58,7 @@ def self.generate_event_resource(resource, date, data_units) end def self.seed - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed ManageIQ::Consumption::ShowbackPricePlan.seed end diff --git a/app/models/manageiq/consumption/showback_charge.rb b/app/models/manageiq/consumption/showback_charge.rb deleted file mode 100644 index 88903d7..0000000 --- a/app/models/manageiq/consumption/showback_charge.rb +++ /dev/null @@ -1,113 +0,0 @@ -class ManageIQ::Consumption::ShowbackCharge < ApplicationRecord - self.table_name = 'showback_charges' - - monetize(:cost_subunits) - - default_value_for :cost, 0 - - belongs_to :showback_event, :inverse_of => :showback_charges - belongs_to :showback_pool, :inverse_of => :showback_charges - - validates :showback_pool, :presence => true, :allow_nil => false - validates :showback_event, :presence => true, :allow_nil => false - - serialize :cost, JSON # Implement cost column as a JSON - serialize :stored_data, JSON # Implement stored_data column as a JSON - before_create :stored_data_event - default_value_for :stored_data, {} - - # Set the cost to 0 - # - def clean_cost - self.cost = 0 - save - end - - # Check if the pool is in a Open State - # - # == Returns: - # A boolean value with true if it's open - # - def open? - showback_pool.state == "OPEN" - end - - # A stored data is created when you create a charge with a snapshoot of the event - # Save the actual data of the event - # - # == Parameters: - # t:: - # A timestamp of the snapshot. This - # can be a timestamp or `Time.now.utc`. - # - def stored_data_event(t = Time.now.utc) - stored_data[t] = showback_event.data unless stored_data != {} - end - - # This returns the data information at the start of the pool - # - # == Returns: - # A json data of the snapshot at start - # - def stored_data_start - stored_data[stored_data.keys.sort.first] || nil - end - - # Get last snapshot of the stored data - # - # == Returns: - # The data information in json format or nil if not exists - # - def stored_data_last - stored_data[stored_data_last_key] || nil - end - - # Get last timestamp of the snapshots - # - # == Returns: - # A timestamp value of the last snapshot - # - def stored_data_last_key - stored_data.keys.sort.last || nil - end - - # This update the last snapshoot of the event - def update_stored_data(t = Time.now.utc) - stored_data.delete(stored_data_last_key) unless stored_data.keys.length == 1 - stored_data[t] = showback_event.data - save - end - - def get_measure(category, dimension) - get_data_measure(stored_data_start, category, dimension) - end - - def get_last_measure(category, dimension) - get_data_measure(stored_data_last, category, dimension) - end - - # This return the category|dimension measure at the start and end of the pool - def get_pool_measure(category, dimension) - [get_data_measure(stored_data_start, category, dimension), - get_data_measure(stored_data_last, category, dimension)] - end - - def calculate_cost(price_plan = nil) - # Find the price plan, there should always be one as it is seeded(Enterprise) - price_plan ||= showback_pool.find_price_plan - if price_plan.class == ManageIQ::Consumption::ShowbackPricePlan - cost = price_plan.calculate_total_cost(showback_event) - save - cost - else - errors.add(:showback_price_plan, _('not found')) - Money.new(0) - end - end - - private - - def get_data_measure(data, category, dimension) - data[category][dimension] || nil if data && data[category] - end -end diff --git a/app/models/manageiq/consumption/showback_event.rb b/app/models/manageiq/consumption/showback_data_rollup.rb similarity index 57% rename from app/models/manageiq/consumption/showback_event.rb rename to app/models/manageiq/consumption/showback_data_rollup.rb index 7c64bdc..fdcf9ab 100644 --- a/app/models/manageiq/consumption/showback_event.rb +++ b/app/models/manageiq/consumption/showback_data_rollup.rb @@ -1,12 +1,12 @@ -class ManageIQ::Consumption::ShowbackEvent < ApplicationRecord +class ManageIQ::Consumption::ShowbackDataRollup < ApplicationRecord belongs_to :resource, :polymorphic => true - has_many :showback_charges, + has_many :showback_data_views, :dependent => :destroy, - :inverse_of => :showback_event - has_many :showback_pools, - :through => :showback_charges, - :inverse_of => :showback_events + :inverse_of => :showback_data_rollup + has_many :showback_envelopes, + :through => :showback_data_views, + :inverse_of => :showback_data_rollups validates :start_time, :end_time, :resource, :presence => true validate :start_time_before_end_time @@ -22,9 +22,9 @@ class ManageIQ::Consumption::ShowbackEvent < ApplicationRecord extend ActiveSupport::Concern - Dir.glob(Pathname.new(File.dirname(__dir__)).join("consumption/showback_event/*")).each { |lib| include_concern lib.split("consumption/showback_event/")[1].split(".rb")[0].upcase } + Dir.glob(Pathname.new(File.dirname(__dir__)).join("consumption/showback_data_rollup/*")).each { |lib| include_concern lib.split("consumption/showback_data_rollup/")[1].split(".rb")[0].upcase } - self.table_name = 'showback_events' + self.table_name = 'showback_data_rollups' def start_time_before_end_time errors.add(:start_time, "Start time should be before end time") unless end_time.to_i >= start_time.to_i @@ -44,43 +44,43 @@ def clean_data def generate_data(data_units = ManageIQ::Consumption::ConsumptionManager.load_column_units) clean_data - ManageIQ::Consumption::ShowbackUsageType.all.each do |measure_type| - next unless resource_type.include?(measure_type.category) - data[measure_type.measure] = {} - measure_type.dimensions.each do |dim| - data[measure_type.measure][dim] = [0, data_units[dim.to_sym] || ""] unless measure_type.measure == "FLAVOR" + ManageIQ::Consumption::ShowbackInputMeasure.all.each do |group_type| + next unless resource_type.include?(group_type.entity) + data[group_type.group] = {} + group_type.fields.each do |dim| + data[group_type.group][dim] = [0, data_units[dim.to_sym] || ""] unless group_type.group == "FLAVOR" end end end def self.events_between_month(start_of_month, end_of_month) - ManageIQ::Consumption::ShowbackEvent.where("start_time >= ? AND end_time <= ?", - DateTime.now.utc.beginning_of_month.change(:month => start_of_month), - DateTime.now.utc.end_of_month.change(:month => end_of_month)) + ManageIQ::Consumption::ShowbackDataRollup.where("start_time >= ? AND end_time <= ?", + DateTime.now.utc.beginning_of_month.change(:month => start_of_month), + DateTime.now.utc.end_of_month.change(:month => end_of_month)) end def self.events_actual_month - ManageIQ::Consumption::ShowbackEvent.where("start_time >= ? AND end_time <= ?", - DateTime.now.utc.beginning_of_month, - DateTime.now.utc.end_of_month) + ManageIQ::Consumption::ShowbackDataRollup.where("start_time >= ? AND end_time <= ?", + DateTime.now.utc.beginning_of_month, + DateTime.now.utc.end_of_month) end def self.events_past_month - ManageIQ::Consumption::ShowbackEvent.where("start_time >= ? AND end_time <= ?", - DateTime.now.utc.beginning_of_month - 1.month, - DateTime.now.utc.end_of_month - 1.month) + ManageIQ::Consumption::ShowbackDataRollup.where("start_time >= ? AND end_time <= ?", + DateTime.now.utc.beginning_of_month - 1.month, + DateTime.now.utc.end_of_month - 1.month) end - def get_measure(category, dimension) - data[category][dimension] if data && data[category] + def get_group(entity, field) + data[entity][field] if data && data[entity] end - def get_measure_unit(category, dimension) - get_measure(category, dimension).last + def get_group_unit(entity, field) + get_group(entity, field).last end - def get_measure_value(category, dimension) - get_measure(category, dimension).first + def get_group_value(entity, field) + get_group(entity, field).first end def last_flavor @@ -94,8 +94,8 @@ def get_key_flavor(key) def update_event(data_units = ManageIQ::Consumption::ConsumptionManager.load_column_units) generate_data(data_units) unless data.present? @metrics = resource.methods.include?(:metrics) ? metrics_time_range(end_time, start_time.end_of_month) : [] - data.each do |key, dimensions| - dimensions.keys.each do |dim| + data.each do |key, fields| + fields.keys.each do |dim| data[key][dim] = [generate_metric(key, dim), data_units[dim.to_sym] || ""] end end @@ -107,7 +107,7 @@ def update_event(data_units = ManageIQ::Consumption::ConsumptionManager.load_col end def generate_metric(key, dim) - key == "FLAVOR" ? send("#{key}_#{dim}") : send("#{key}_#{dim}", get_measure_value(key, dim).to_d) + key == "FLAVOR" ? send("#{key}_#{dim}") : send("#{key}_#{dim}", get_group_value(key, dim).to_d) end def collect_tags @@ -117,9 +117,9 @@ def collect_tags self.context["tag"] = {} unless self.context.key?("tag") end resource.tagged_with(:ns => '/managed').each do |tag| - category = tag.classification.category - self.context["tag"][category] = [] unless self.context["tag"].key?(category) - self.context["tag"][category] << tag.classification.name unless self.context["tag"][category].include?(tag.classification.name) + entity = tag.classification.entity + self.context["tag"][entity] = [] unless self.context["tag"].key?(entity) + self.context["tag"][entity] << tag.classification.name unless self.context["tag"][entity].include?(tag.classification.name) end end @@ -151,7 +151,7 @@ def month_duration # Find a pool def find_pool(res) - ManageIQ::Consumption::ShowbackPool.find_by( + ManageIQ::Consumption::ShowbackEnvelope.find_by( :resource => res, :state => "OPEN" ) @@ -168,20 +168,20 @@ def assign_resource def assign_by_tag return unless context.key?("tag") - context["tag"].each do |category, array_children| - t = Tag.find_by_classification_name(category) + context["tag"].each do |entity, array_children| + t = Tag.find_by_classification_name(entity) find_pool(t)&.add_event(self) - array_children.each do |child_category| - tag_child = t.classification.children.detect { |c| c.name == child_category } + array_children.each do |child_entity| + tag_child = t.classification.children.detect { |c| c.name == child_entity } find_pool(tag_child.tag)&.add_event(self) end end end def update_charges - ManageIQ::Consumption::ShowbackCharge.where(:showback_event=>self).each do |charge| + ManageIQ::Consumption::ShowbackDataView.where(:showback_data_rollup=>self).each do |charge| if charge.open? - charge.update_stored_data + charge.update_data_snapshot end end end diff --git a/app/models/manageiq/consumption/showback_event/cpu.rb b/app/models/manageiq/consumption/showback_data_rollup/cpu.rb similarity index 94% rename from app/models/manageiq/consumption/showback_event/cpu.rb rename to app/models/manageiq/consumption/showback_data_rollup/cpu.rb index d57521c..a593f57 100644 --- a/app/models/manageiq/consumption/showback_event/cpu.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/cpu.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::CPU +module ManageIQ::Consumption::ShowbackDataRollup::CPU # # Return the average acumulated with the new one # diff --git a/app/models/manageiq/consumption/showback_event/disk.rb b/app/models/manageiq/consumption/showback_data_rollup/disk.rb similarity index 60% rename from app/models/manageiq/consumption/showback_event/disk.rb rename to app/models/manageiq/consumption/showback_data_rollup/disk.rb index 34f76d9..fffd871 100644 --- a/app/models/manageiq/consumption/showback_event/disk.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/disk.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::DISK +module ManageIQ::Consumption::ShowbackDataRollup::DISK # for old chargeback integration def disk_io_disk_usage_rate_average end diff --git a/app/models/manageiq/consumption/showback_event/fixed.rb b/app/models/manageiq/consumption/showback_data_rollup/fixed.rb similarity index 71% rename from app/models/manageiq/consumption/showback_event/fixed.rb rename to app/models/manageiq/consumption/showback_data_rollup/fixed.rb index 2b77b83..e61fd40 100644 --- a/app/models/manageiq/consumption/showback_event/fixed.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/fixed.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::FIXED +module ManageIQ::Consumption::ShowbackDataRollup::FIXED def fixed_fixed_compute_1 end diff --git a/app/models/manageiq/consumption/showback_event/flavor.rb b/app/models/manageiq/consumption/showback_data_rollup/flavor.rb similarity index 94% rename from app/models/manageiq/consumption/showback_event/flavor.rb rename to app/models/manageiq/consumption/showback_data_rollup/flavor.rb index 92cb083..d412b95 100644 --- a/app/models/manageiq/consumption/showback_event/flavor.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/flavor.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::FLAVOR +module ManageIQ::Consumption::ShowbackDataRollup::FLAVOR # # Return Number Ocurrences # diff --git a/app/models/manageiq/consumption/showback_event/mem.rb b/app/models/manageiq/consumption/showback_data_rollup/mem.rb similarity index 86% rename from app/models/manageiq/consumption/showback_event/mem.rb rename to app/models/manageiq/consumption/showback_data_rollup/mem.rb index f80c8fc..d2e80e8 100644 --- a/app/models/manageiq/consumption/showback_event/mem.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/mem.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::MEM +module ManageIQ::Consumption::ShowbackDataRollup::MEM # # Return the average acumulated with the new one # diff --git a/app/models/manageiq/consumption/showback_event/metering.rb b/app/models/manageiq/consumption/showback_data_rollup/metering.rb similarity index 57% rename from app/models/manageiq/consumption/showback_event/metering.rb rename to app/models/manageiq/consumption/showback_data_rollup/metering.rb index e91df56..b7634ff 100644 --- a/app/models/manageiq/consumption/showback_event/metering.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/metering.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::METERING +module ManageIQ::Consumption::ShowbackDataRollup::METERING # for old chargeback integration def metering_metering_used_hours end diff --git a/app/models/manageiq/consumption/showback_event/net.rb b/app/models/manageiq/consumption/showback_data_rollup/net.rb similarity index 60% rename from app/models/manageiq/consumption/showback_event/net.rb rename to app/models/manageiq/consumption/showback_data_rollup/net.rb index c8d0b1d..a3e2579 100644 --- a/app/models/manageiq/consumption/showback_event/net.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/net.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::NET +module ManageIQ::Consumption::ShowbackDataRollup::NET # for old chargeback integration def net_io_net_usage_rate_average end diff --git a/app/models/manageiq/consumption/showback_event/storage.rb b/app/models/manageiq/consumption/showback_data_rollup/storage.rb similarity index 71% rename from app/models/manageiq/consumption/showback_event/storage.rb rename to app/models/manageiq/consumption/showback_data_rollup/storage.rb index 25762d2..9f7fef4 100644 --- a/app/models/manageiq/consumption/showback_event/storage.rb +++ b/app/models/manageiq/consumption/showback_data_rollup/storage.rb @@ -1,4 +1,4 @@ -module ManageIQ::Consumption::ShowbackEvent::STORAGE +module ManageIQ::Consumption::ShowbackDataRollup::STORAGE # for old chargeback integration def storage_derived_vm_used_disk_storage end diff --git a/app/models/manageiq/consumption/showback_data_view.rb b/app/models/manageiq/consumption/showback_data_view.rb new file mode 100644 index 0000000..33c2d0c --- /dev/null +++ b/app/models/manageiq/consumption/showback_data_view.rb @@ -0,0 +1,117 @@ +class ManageIQ::Consumption::ShowbackDataView < ApplicationRecord + self.table_name = 'showback_data_views' + + monetize(:cost_subunits) + + default_value_for :cost, 0 + + belongs_to :showback_data_rollup, :inverse_of => :showback_data_views + belongs_to :showback_envelope, :inverse_of => :showback_data_views + + validates :showback_envelope, :presence => true, :allow_nil => false + validates :showback_data_rollup, :presence => true, :allow_nil => false + + serialize :cost, JSON # Implement cost column as a JSON + serialize :data_snapshot, JSON # Implement data_snapshot column as a JSON + serialize :context_snapshot, JSON # Implement context_snapshot column as a JSON + before_create :snapshot_event + default_value_for :data_snapshot, {} + default_value_for :context_snapshot, {} + + + # Set the cost to 0 + # + def clean_cost + self.cost = 0 + save + end + + # Check if the pool is in a Open State + # + # == Returns: + # A boolean value with true if it's open + # + def open? + showback_envelope.state == "OPEN" + end + + # A stored data is created when you create a charge with a snapshoot of the event + # Save the actual data of the event + # + # == Parameters: + # t:: + # A timestamp of the snapshot. This + # can be a timestamp or `Time.now.utc`. + # + def snapshot_event(t = Time.now.utc) + data_snapshot[t] = showback_data_rollup.data unless data_snapshot != {} + context_snapshot = showback_data_rollup.context + end + + # This returns the data information at the start of the pool + # + # == Returns: + # A json data of the snapshot at start + # + def data_snapshot_start + data_snapshot[data_snapshot.keys.sort.first] || nil + end + + # Get last snapshot of the stored data + # + # == Returns: + # The data information in json format or nil if not exists + # + def data_snapshot_last + data_snapshot[data_snapshot_last_key] || nil + end + + # Get last timestamp of the snapshots + # + # == Returns: + # A timestamp value of the last snapshot + # + def data_snapshot_last_key + data_snapshot.keys.sort.last || nil + end + + # This update the last snapshoot of the event + def update_data_snapshot(t = Time.now.utc) + data_snapshot.delete(data_snapshot_last_key) unless data_snapshot.keys.length == 1 + data_snapshot[t] = showback_data_rollup.data + save + end + + def get_group(entity, field) + get_data_group(data_snapshot_start, entity, field) + end + + def get_last_group(entity, field) + get_data_group(data_snapshot_last, entity, field) + end + + # This return the entity|field group at the start and end of the pool + def get_pool_group(entity, field) + [get_data_group(data_snapshot_start, entity, field), + get_data_group(data_snapshot_last, entity, field)] + end + + def calculate_cost(price_plan = nil) + # Find the price plan, there should always be one as it is seeded(Enterprise) + price_plan ||= showback_envelope.find_price_plan + if price_plan.class == ManageIQ::Consumption::ShowbackPricePlan + cost = price_plan.calculate_total_cost(showback_data_rollup) + save + cost + else + errors.add(:showback_price_plan, _('not found')) + Money.new(0) + end + end + + private + + def get_data_group(data, entity, field) + data[entity][field] || nil if data && data[entity] + end +end diff --git a/app/models/manageiq/consumption/showback_pool.rb b/app/models/manageiq/consumption/showback_envelope.rb similarity index 51% rename from app/models/manageiq/consumption/showback_pool.rb rename to app/models/manageiq/consumption/showback_envelope.rb index be4ba36..7b031a1 100644 --- a/app/models/manageiq/consumption/showback_pool.rb +++ b/app/models/manageiq/consumption/showback_envelope.rb @@ -1,5 +1,5 @@ -class ManageIQ::Consumption::ShowbackPool < ApplicationRecord - self.table_name = 'showback_pools' +class ManageIQ::Consumption::ShowbackEnvelope < ApplicationRecord + self.table_name = 'showback_envelopes' belongs_to :resource, :polymorphic => true @@ -8,12 +8,12 @@ class ManageIQ::Consumption::ShowbackPool < ApplicationRecord before_save :check_pool_state, :if => :state_changed? - has_many :showback_charges, + has_many :showback_data_views, :dependent => :destroy, - :inverse_of => :showback_pool - has_many :showback_events, - :through => :showback_charges, - :inverse_of => :showback_pools + :inverse_of => :showback_envelope + has_many :showback_data_rollups, + :through => :showback_data_views, + :inverse_of => :showback_envelopes validates :name, :presence => true validates :description, :presence => true @@ -35,37 +35,37 @@ def check_pool_state # s_time = (self.start_time + 1.months).beginning_of_month # This is never used s_time = end_time != start_time.end_of_month ? end_time : (start_time + 1.month).beginning_of_month e_time = s_time.end_of_month - generate_pool(s_time, e_time) unless ManageIQ::Consumption::ShowbackPool.exists?(:resource => resource, :start_time => s_time) + generate_pool(s_time, e_time) unless ManageIQ::Consumption::ShowbackEnvelope.exists?(:resource => resource, :start_time => s_time) when 'PROCESSING' then raise _("Pool can't change state to OPEN from PROCESSING") unless state != 'OPEN' when 'CLOSED' then raise _("Pool can't change state when it's CLOSED") end end - def add_event(event) - if event.kind_of?(ManageIQ::Consumption::ShowbackEvent) + def add_event(data_rollup) + if data_rollup.kind_of?(ManageIQ::Consumption::ShowbackDataRollup) # verify that the event is not already there - if showback_events.include?(event) - errors.add(:showback_events, 'duplicate') + if showback_data_rollups.include?(data_rollup) + errors.add(:showback_data_rollups, 'duplicate') else - charge = ManageIQ::Consumption::ShowbackCharge.new(:showback_event => event, :showback_pool => self) + charge = ManageIQ::Consumption::ShowbackDataView.new(:showback_data_rollup => data_rollup, :showback_envelope => self) charge.save end else - errors.add(:showback_events, "Error Type #{event.type} is not ManageIQ::Consumption::ShowbackEvent") + errors.add(:showback_data_rollups, "Error Type #{data_rollup.type} is not ManageIQ::Consumption::ShowbackEvent") end end # Remove events from a pool, no error is thrown def remove_event(event) - if event.kind_of?(ManageIQ::Consumption::ShowbackEvent) - if showback_events.include?(event) - showback_events.delete(event) + if event.kind_of?(ManageIQ::Consumption::ShowbackDataRollup) + if showback_data_rollups.include?(event) + showback_data_rollups.delete(event) else - errors.add(:showback_events, "not found") + errors.add(:showback_data_rollups, "not found") end else - errors.add(:showback_events, "Error Type #{event.type} is not ManageIQ::Consumption::ShowbackEvent") + errors.add(:showback_data_rollups, "Error Type #{event.type} is not ManageIQ::Consumption::ShowbackEvent") end end @@ -91,9 +91,9 @@ def add_charge(input, cost) # updates an existing charge if ch ch.cost = Money.new(cost) - elsif input.class == ManageIQ::Consumption::ShowbackEvent # Or create a new one - ch = showback_charges.new(:showback_event => input, - :cost => cost) + elsif input.class == ManageIQ::Consumption::ShowbackDataRollup # Or create a new one + ch = showback_data_views.new(:showback_data_rollup => input, + :cost => cost) else errors.add(:input, 'bad class') return @@ -110,33 +110,33 @@ def clear_charge(input) def sum_of_charges a = Money.new(0) - showback_charges.each do |x| + showback_data_views.each do |x| a += x.cost if x.cost end a end def clean_all_charges - showback_charges.each(&:clean_cost) + showback_data_views.each(&:clean_cost) end def calculate_charge(input) ch = find_charge(input) - if ch.kind_of?(ManageIQ::Consumption::ShowbackCharge) + if ch.kind_of?(ManageIQ::Consumption::ShowbackDataView) ch.cost = ch.calculate_cost(find_price_plan) || Money.new(0) save elsif input.nil? - errors.add(:showback_charge, 'not found') + errors.add(:showback_data_view, 'not found') Money.new(0) else - input.errors.add(:showback_charge, 'not found') + input.errors.add(:showback_data_view, 'not found') Money.new(0) end end def calculate_all_charges # plan = find_price_plan - showback_charges.each do |x| + showback_data_views.each do |x| calculate_charge(x) end end @@ -154,9 +154,9 @@ def find_price_plan end def find_charge(input) - if input.kind_of?(ManageIQ::Consumption::ShowbackEvent) - showback_charges.find_by(:showback_event => input, :showback_pool => self) - elsif input.kind_of?(ManageIQ::Consumption::ShowbackCharge) && (input.showback_pool == self) + if input.kind_of?(ManageIQ::Consumption::ShowbackDataRollup) + showback_data_views.find_by(:showback_data_rollup => input, :showback_envelope => self) + elsif input.kind_of?(ManageIQ::Consumption::ShowbackDataView) && (input.showback_envelope == self) input end end @@ -164,20 +164,20 @@ def find_charge(input) private def generate_pool(s_time, e_time) - pool = ManageIQ::Consumption::ShowbackPool.create(:name => name, - :description => description, - :resource => resource, - :start_time => s_time, - :end_time => e_time, - :state => 'OPEN') - showback_charges.each do |charge| - ManageIQ::Consumption::ShowbackCharge.create(:stored_data => { - charge.stored_data_last_key => charge.stored_data_last - }, - :showback_event => charge.showback_event, - :showback_pool => pool, - :cost_subunits => charge.cost_subunits, - :cost_currency => charge.cost_currency) + pool = ManageIQ::Consumption::ShowbackEnvelope.create(:name => name, + :description => description, + :resource => resource, + :start_time => s_time, + :end_time => e_time, + :state => 'OPEN') + showback_data_views.each do |charge| + ManageIQ::Consumption::ShowbackDataView.create(:stored_data => { + charge.stored_data_last_key => charge.stored_data_last + }, + :showback_data_rollup => charge.showback_event, + :showback_envelope => pool, + :cost_subunits => charge.cost_subunits, + :cost_currency => charge.cost_currency) end end end diff --git a/app/models/manageiq/consumption/showback_input_measure.rb b/app/models/manageiq/consumption/showback_input_measure.rb new file mode 100644 index 0000000..a013d9d --- /dev/null +++ b/app/models/manageiq/consumption/showback_input_measure.rb @@ -0,0 +1,33 @@ +class ManageIQ::Consumption::ShowbackInputMeasure < ApplicationRecord + validates :description, :entity, :group, :fields, :presence => true + + serialize :fields, Array + + self.table_name = "showback_input_measures" + + def name + "#{entity}::#{group}" + end + + def self.seed + seed_data.each do |input_group_attributtes| + input_measure_entity = input_group_attributtes[:entity] + input_measure_group = input_group_attributtes[:group] + next if ManageIQ::Consumption::ShowbackInputMeasure.find_by(:entity => input_measure_entity, :group => input_measure_group) + log_attrs = input_group_attributtes.slice(:entity, :description, :group, :fields) + _log.info("Creating consumption usage type with parameters #{log_attrs.inspect}") + _log.info("Creating #{input_measure_entity} consumption usage type...") + input_measure_new = create(input_group_attributtes) + input_measure_new.save + _log.info("Creating #{input_measure_entity} consumption usage type... Complete") + end + end + + def self.seed_file_name + @seed_file_name ||= Pathname.new(Gem.loaded_specs['manageiq-consumption'].full_gem_path).join("db", "fixtures", "#{table_name}.yml") + end + + def self.seed_data + File.exist?(seed_file_name) ? YAML.load_file(seed_file_name) : [] + end +end diff --git a/app/models/manageiq/consumption/showback_price_plan.rb b/app/models/manageiq/consumption/showback_price_plan.rb index 4b03591..0bba657 100644 --- a/app/models/manageiq/consumption/showback_price_plan.rb +++ b/app/models/manageiq/consumption/showback_price_plan.rb @@ -25,11 +25,11 @@ def calculate_list_of_costs(event, cycle_duration = nil) resource_type = event.resource&.type || event.resource_type # Accumulator tc = [] - # For each measure type in ShowbackUsageType, I need to find the rates applying to the different dimensions - # If there is a rate associated to it, we call it with a measure (that can be 0) - ManageIQ::Consumption::ShowbackUsageType.where(:category => resource_type).each do |usage| - usage.dimensions.each do |dim| - rates = showback_rates.where(:category => usage.category, :measure => usage.measure, :dimension => dim) + # For each group type in ShowbackUsageType, I need to find the rates applying to the different fields + # If there is a rate associated to it, we call it with a group (that can be 0) + ManageIQ::Consumption::ShowbackInputMeasure.where(:entity => resource_type).each do |usage| + usage.fields.each do |dim| + rates = showback_rates.where(:entity => usage.entity, :group => usage.group, :field => dim) rates.each do |r| next unless ManageIQ::Consumption::UtilsHelper.included_in?(event.context, r.screener) tc << [r.rate(event, cycle_duration), r] @@ -46,7 +46,7 @@ def calculate_list_of_costs_input(resource_type:, start_time: nil, end_time: nil, cycle_duration: nil) - event = ManageIQ::Consumption::ShowbackEvent.new + event = ManageIQ::Consumption::ShowbackDataRollup.new event.resource_type = resource_type event.data = data event.context = context || {} diff --git a/app/models/manageiq/consumption/showback_rate.rb b/app/models/manageiq/consumption/showback_rate.rb index f93a65e..9438f06 100644 --- a/app/models/manageiq/consumption/showback_rate.rb +++ b/app/models/manageiq/consumption/showback_rate.rb @@ -7,12 +7,12 @@ class ShowbackRate < ApplicationRecord has_many :showback_tiers, :inverse_of => :showback_rate validates :calculation, :presence => true, :inclusion => { :in => VALID_RATE_CALCULATIONS } - validates :category, :presence => true - validates :dimension, :presence => true + validates :entity, :presence => true + validates :field, :presence => true # There is no fixed_rate unit (only presence or not, and time), TODO: change column name in a migration - validates :measure, :presence => true - default_value_for :measure, '' + validates :group, :presence => true + default_value_for :group, '' serialize :screener, JSON # Implement data column as a JSON default_value_for :screener, { } @@ -27,14 +27,14 @@ class ShowbackRate < ApplicationRecord # @return [Boolean] default_value_for :tiers_use_full_value, true - default_value_for :step_variable, '' + default_value_for :tier_input_variable, '' validates :screener, :exclusion => { :in => [nil] } after_create :create_zero_tier def name - "#{category}:#{measure}:#{dimension}" + "#{entity}:#{group}:#{field}" end # Create a Zero tier when the rate is create @@ -51,10 +51,10 @@ def rate(event, cycle_duration = nil) # Find tier (use context) # Calculate value within tier # For each tier used, calculate costs - value, measurement = event.get_measure(measure, dimension) # Returns measure and the unit + value, groupment = event.get_group(group, field) # Returns group and the unit tiers = get_tiers(value || 0) duration = cycle_duration || event.month_duration - # To do event.resource.type should be eq to category + # To do event.resource.type should be eq to entity acc = 0 adjusted_value = value # Just in case we need to update it # If there is a step defined, we use it to adjust input to it @@ -63,21 +63,21 @@ def rate(event, cycle_duration = nil) unless tier.step_value.nil? || tier.step_unit.nil? # Convert step and value to the same unit (variable_rate_per_unit) and calculate real values with the minimum step) adjusted_step = UnitsConverterHelper.to_unit(tier.step_value, tier.step_unit, tier.variable_rate_per_unit) - tier_start_value = UnitsConverterHelper.to_unit(tier.tier_start_value, step_variable, measurement) + tier_start_value = UnitsConverterHelper.to_unit(tier.tier_start_value, tier_input_variable, groupment) tier_value = tiers_use_full_value ? value : value - tier_start_value - divmod = UnitsConverterHelper.to_unit(tier_value, measurement, tier.variable_rate_per_unit).divmod(adjusted_step) + divmod = UnitsConverterHelper.to_unit(tier_value, groupment, tier.variable_rate_per_unit).divmod(adjusted_step) adjusted_value = (divmod[0] + (divmod[1].zero? ? 0 : 1)) * adjusted_step - measurement = tier.variable_rate_per_unit # Updated value with new measurement as we have updated values + groupment = tier.variable_rate_per_unit # Updated value with new groupment as we have updated values end # If there is a step time defined, we use it to adjust input to it adjusted_time_span = event.time_span - acc += rate_with_values(tier, adjusted_value, measurement, adjusted_time_span, duration) + acc += rate_with_values(tier, adjusted_value, groupment, adjusted_time_span, duration) end acc end - def rate_with_values(tier, value, measure, time_span, cycle_duration, date = Time.current) - send(calculation.downcase, tier, value, measure, time_span, cycle_duration, date) + def rate_with_values(tier, value, group, time_span, cycle_duration, date = Time.current) + send(calculation.downcase, tier, value, group, time_span, cycle_duration, date) end private @@ -90,7 +90,7 @@ def get_tiers(value) end end - def occurrence(tier, value, _measure, _time_span, cycle_duration, date) + def occurrence(tier, value, _group, _time_span, cycle_duration, date) # Returns fixed_cost always + variable_cost sometimes # Fixed cost are always added fully, variable costs are only added if value is not nil # fix_inter: number of intervals in the calculation => how many times do we need to apply the rate to get a monthly (cycle) rate (min = 1) @@ -109,7 +109,7 @@ def occurrence(tier, value, _measure, _time_span, cycle_duration, date) fix_inter * tier.fixed_rate + (value ? var_inter * tier.variable_rate : 0) # fixed always, variable if value end - def duration(tier, value, measure, time_span, cycle_duration, date) + def duration(tier, value, group, time_span, cycle_duration, date) # Returns fixed_cost + variable costs taking into account value and duration # Fixed cost and variable costs are prorated on time # time_span = end_time - start_time (duration of the event) @@ -128,11 +128,11 @@ def duration(tier, value, measure, time_span, cycle_duration, date) :interval => tier.variable_rate_per_time, :calculation_date => date ) - value_in_rate_units = UnitsConverterHelper.to_unit(value.to_f, measure, tier.variable_rate_per_unit) || 0 + value_in_rate_units = UnitsConverterHelper.to_unit(value.to_f, group, tier.variable_rate_per_unit) || 0 ((fix_inter * tier.fixed_rate) + (var_inter * value_in_rate_units * tier.variable_rate)) * time_span.to_f / cycle_duration end - def quantity(tier, value, measure, _time_span, cycle_duration, date) + def quantity(tier, value, group, _time_span, cycle_duration, date) # Returns costs based on quantity (independently of duration). # Fixed cost are calculated per period (i.e. 5€/month). You could use occurrence or duration # time_span = end_time - start_time @@ -145,7 +145,7 @@ def quantity(tier, value, measure, _time_span, cycle_duration, date) :interval => tier.fixed_rate_per_time, :calculation_date => date ) - value_in_rate_units = UnitsConverterHelper.to_unit(value, measure, tier.variable_rate_per_unit) || 0 + value_in_rate_units = UnitsConverterHelper.to_unit(value, group, tier.variable_rate_per_unit) || 0 (fix_inter * tier.fixed_rate) + (value_in_rate_units * tier.variable_rate) end end diff --git a/app/models/manageiq/consumption/showback_tier.rb b/app/models/manageiq/consumption/showback_tier.rb index 3b9d1df..410974c 100644 --- a/app/models/manageiq/consumption/showback_tier.rb +++ b/app/models/manageiq/consumption/showback_tier.rb @@ -45,7 +45,7 @@ class ShowbackTier < ApplicationRecord # # @return [String] the definition of the object def name - "#{showback_rate.category}:#{showback_rate.measure}:#{showback_rate.dimension}:Tier:#{tier_start_value}-#{tier_end_value}" + "#{showback_rate.entity}:#{showback_rate.group}:#{showback_rate.field}:Tier:#{tier_start_value}-#{tier_end_value}" end # Validate the interval bvefore save diff --git a/app/models/manageiq/consumption/showback_usage_type.rb b/app/models/manageiq/consumption/showback_usage_type.rb deleted file mode 100644 index abe23ff..0000000 --- a/app/models/manageiq/consumption/showback_usage_type.rb +++ /dev/null @@ -1,33 +0,0 @@ -class ManageIQ::Consumption::ShowbackUsageType < ApplicationRecord - validates :description, :category, :measure, :dimensions, :presence => true - - serialize :dimensions, Array - - self.table_name = "showback_usage_types" - - def name - "#{category}::#{measure}" - end - - def self.seed - seed_data.each do |usage_type_attributtes| - usage_type_name = usage_type_attributtes[:category] - usage_type_measure = usage_type_attributtes[:measure] - next if ManageIQ::Consumption::ShowbackUsageType.find_by(:category => usage_type_name, :measure => usage_type_measure) - log_attrs = usage_type_attributtes.slice(:category, :description, :measure, :dimensions) - _log.info("Creating consumption usage type with parameters #{log_attrs.inspect}") - _log.info("Creating #{usage_type_name} consumption usage type...") - usage_new = create(usage_type_attributtes) - usage_new.save - _log.info("Creating #{usage_type_name} consumption usage type... Complete") - end - end - - def self.seed_file_name - @seed_file_name ||= Pathname.new(Gem.loaded_specs['manageiq-consumption'].full_gem_path).join("db", "fixtures", "#{table_name}.yml") - end - - def self.seed_data - File.exist?(seed_file_name) ? YAML.load_file(seed_file_name) : [] - end -end diff --git a/db/fixtures/showback_input_measures.yml b/db/fixtures/showback_input_measures.yml new file mode 100644 index 0000000..7cca39b --- /dev/null +++ b/db/fixtures/showback_input_measures.yml @@ -0,0 +1,116 @@ +--- +- :entity: "Vm" + :description: "Calculate CPU Showback of VM" + :group: "CPU" + :fields: ["average", "number", "max_number_of_cpu"] +- :entity: "Vm" + :description: "Calculate MEM Showback of VM" + :group: "MEM" + :fields: ["max_mem"] +- :entity: "Vm" + :description: "Template Showback of VM" + :group: "FLAVOR" + :fields: ["cpu_reserved","memory_reserved"] +- :entity: "Container" + :description: "Calculate CPU Showback of Container" + :group: "CPU" + :fields: ["max_number_of_cpu"] +- :entity: "Container" + :description: "Calculate MEM Showback of Container" + :group: "MEM" + :fields: ["max_mem"] +- :entity: "Container" + :description: "Template Showback of VM" + :group: "FLAVOR" + :fields: ["cpu_reserved","memory_reserved"] +# For integration with old chargeback +- :entity: "Container" + :description: "TBD" + :group: "cpu" + :fields: ["cpu_usagemhz_rate_average"] +- :entity: "Container" + :description: "TBD" + :group: "cpu_cores" + :fields: ["v_derived_cpu_total_cores_used", "derived_vm_numvcpus", "cpu_usage_rate_average"] +- :entity: "Container" + :description: "TBD" + :group: "memory" + :fields: ["derived_memory_used", "derived_memory_available"] +- :entity: "Container" + :description: "TBD" + :group: "net_io" + :fields: ["net_usage_rate_average"] +- :entity: "Container" + :description: "TBD" + :group: "disk_io" + :fields: ["disk_usage_rate_average"] +- :entity: "Container" + :description: "TBD" + :group: "fixed" + :fields: ["fixed_compute_1", "fixed_compute_2", "fixed_storage_1", "fixed_storage_2"] + +- :entity: "Container" + :description: "TBD" + :group: "metering" + :fields: ["metering_used_hours"] +- :entity: "ContainerImage" + :description: "TBD" + :group: "cpu" + :fields: ["cpu_usagemhz_rate_average"] +- :entity: "ContainerImage" + :description: "TBD" + :group: "cpu_cores" + :fields: ["v_derived_cpu_total_cores_used", "derived_vm_numvcpus", "cpu_usage_rate_average"] +- :entity: "ContainerImage" + :description: "TBD" + :group: "memory" + :fields: ["derived_memory_used", "derived_memory_available"] +- :entity: "ContainerImage" + :description: "TBD" + :group: "net_io" + :fields: ["net_usage_rate_average"] +- :entity: "ContainerImage" + :description: "TBD" + :group: "disk_io" + :fields: ["disk_usage_rate_average"] +- :entity: "ContainerImage" + :description: "TBD" + :group: "fixed" + :fields: ["fixed_compute_1", "fixed_compute_2", "fixed_storage_1", "fixed_storage_2"] +- :entity: "ContainerImage" + :description: "TBD" + :group: "metering" + :fields: ["metering_used_hours"] + +- :entity: "Vm" + :description: "TBD" + :group: "cpu" + :fields: ["derived_vm_numvcpus", "cpu_usagemhz_rate_average"] +- :entity: "Vm" + :description: "TBD" + :group: "cpu_cores" + :fields: ["v_derived_cpu_total_cores_used", "cpu_usage_rate_average"] +- :entity: "Vm" + :description: "TBD" + :group: "memory" + :fields: ["derived_memory_used", "derived_memory_available"] +- :entity: "Vm" + :description: "TBD" + :group: "net_io" + :fields: ["net_usage_rate_average"] +- :entity: "Vm" + :description: "TBD" + :group: "disk_io" + :fields: ["disk_usage_rate_average"] +- :entity: "Vm" + :description: "TBD" + :group: "fixed" + :fields: ["fixed_compute_1", "fixed_compute_2", "fixed_storage_1", "fixed_storage_2", "fixed_storage_2", "fixed_storage_1"] +- :entity: "Vm" + :description: "TBD" + :group: "metering" + :fields: ["metering_used_hours"] +- :entity: "Vm" + :description: "TBD" + :group: "storage" + :fields: ["derived_vm_allocated_disk_storage", "derived_vm_used_disk_storage"] diff --git a/db/fixtures/showback_usage_types.yml b/db/fixtures/showback_usage_types.yml deleted file mode 100644 index 9b00252..0000000 --- a/db/fixtures/showback_usage_types.yml +++ /dev/null @@ -1,116 +0,0 @@ ---- -- :category: "Vm" - :description: "Calculate CPU Showback of VM" - :measure: "CPU" - :dimensions: ["average", "number", "max_number_of_cpu"] -- :category: "Vm" - :description: "Calculate MEM Showback of VM" - :measure: "MEM" - :dimensions: ["max_mem"] -- :category: "Vm" - :description: "Template Showback of VM" - :measure: "FLAVOR" - :dimensions: ["cpu_reserved","memory_reserved"] -- :category: "Container" - :description: "Calculate CPU Showback of Container" - :measure: "CPU" - :dimensions: ["max_number_of_cpu"] -- :category: "Container" - :description: "Calculate MEM Showback of Container" - :measure: "MEM" - :dimensions: ["max_mem"] -- :category: "Container" - :description: "Template Showback of VM" - :measure: "FLAVOR" - :dimensions: ["cpu_reserved","memory_reserved"] -# For integration with old chargeback -- :category: "Container" - :description: "TBD" - :measure: "cpu" - :dimensions: ["cpu_usagemhz_rate_average"] -- :category: "Container" - :description: "TBD" - :measure: "cpu_cores" - :dimensions: ["v_derived_cpu_total_cores_used", "derived_vm_numvcpus", "cpu_usage_rate_average"] -- :category: "Container" - :description: "TBD" - :measure: "memory" - :dimensions: ["derived_memory_used", "derived_memory_available"] -- :category: "Container" - :description: "TBD" - :measure: "net_io" - :dimensions: ["net_usage_rate_average"] -- :category: "Container" - :description: "TBD" - :measure: "disk_io" - :dimensions: ["disk_usage_rate_average"] -- :category: "Container" - :description: "TBD" - :measure: "fixed" - :dimensions: ["fixed_compute_1", "fixed_compute_2", "fixed_storage_1", "fixed_storage_2"] - -- :category: "Container" - :description: "TBD" - :measure: "metering" - :dimensions: ["metering_used_hours"] -- :category: "ContainerImage" - :description: "TBD" - :measure: "cpu" - :dimensions: ["cpu_usagemhz_rate_average"] -- :category: "ContainerImage" - :description: "TBD" - :measure: "cpu_cores" - :dimensions: ["v_derived_cpu_total_cores_used", "derived_vm_numvcpus", "cpu_usage_rate_average"] -- :category: "ContainerImage" - :description: "TBD" - :measure: "memory" - :dimensions: ["derived_memory_used", "derived_memory_available"] -- :category: "ContainerImage" - :description: "TBD" - :measure: "net_io" - :dimensions: ["net_usage_rate_average"] -- :category: "ContainerImage" - :description: "TBD" - :measure: "disk_io" - :dimensions: ["disk_usage_rate_average"] -- :category: "ContainerImage" - :description: "TBD" - :measure: "fixed" - :dimensions: ["fixed_compute_1", "fixed_compute_2", "fixed_storage_1", "fixed_storage_2"] -- :category: "ContainerImage" - :description: "TBD" - :measure: "metering" - :dimensions: ["metering_used_hours"] - -- :category: "Vm" - :description: "TBD" - :measure: "cpu" - :dimensions: ["derived_vm_numvcpus", "cpu_usagemhz_rate_average"] -- :category: "Vm" - :description: "TBD" - :measure: "cpu_cores" - :dimensions: ["v_derived_cpu_total_cores_used", "cpu_usage_rate_average"] -- :category: "Vm" - :description: "TBD" - :measure: "memory" - :dimensions: ["derived_memory_used", "derived_memory_available"] -- :category: "Vm" - :description: "TBD" - :measure: "net_io" - :dimensions: ["net_usage_rate_average"] -- :category: "Vm" - :description: "TBD" - :measure: "disk_io" - :dimensions: ["disk_usage_rate_average"] -- :category: "Vm" - :description: "TBD" - :measure: "fixed" - :dimensions: ["fixed_compute_1", "fixed_compute_2", "fixed_storage_1", "fixed_storage_2", "fixed_storage_2", "fixed_storage_1"] -- :category: "Vm" - :description: "TBD" - :measure: "metering" - :dimensions: ["metering_used_hours"] -- :category: "Vm" - :description: "TBD" - :measure: "storage" - :dimensions: ["derived_vm_allocated_disk_storage", "derived_vm_used_disk_storage"] diff --git a/spec/factories/showback_event.rb b/spec/factories/showback_data_rollup.rb similarity index 92% rename from spec/factories/showback_event.rb rename to spec/factories/showback_data_rollup.rb index b694b43..476a6c7 100644 --- a/spec/factories/showback_event.rb +++ b/spec/factories/showback_data_rollup.rb @@ -1,5 +1,5 @@ FactoryGirl.define do - factory :showback_event, :class => ManageIQ::Consumption::ShowbackEvent do + factory :showback_data_rollup, :class => ManageIQ::Consumption::ShowbackDataRollup do association :resource, :factory => :vm start_time 4.hours.ago end_time 1.hour.ago diff --git a/spec/factories/showback_charge.rb b/spec/factories/showback_data_view.rb similarity index 77% rename from spec/factories/showback_charge.rb rename to spec/factories/showback_data_view.rb index 982938c..e5b8870 100644 --- a/spec/factories/showback_charge.rb +++ b/spec/factories/showback_data_view.rb @@ -1,12 +1,13 @@ FactoryGirl.define do - factory :showback_charge, :class => ManageIQ::Consumption::ShowbackCharge do - showback_pool - showback_event + factory :showback_data_view, :class => ManageIQ::Consumption::ShowbackDataView do + showback_envelope + showback_data_rollup cost 0 - stored_data { { } } + data_snapshot { { } } + context_snapshot { { } } - trait :with_stored_data do - stored_data do + trait :with_data_snapshot do + data_snapshot do { Time.now.utc.beginning_of_month => { "CPU" => { diff --git a/spec/factories/showback_pool.rb b/spec/factories/showback_envelope.rb similarity index 86% rename from spec/factories/showback_pool.rb rename to spec/factories/showback_envelope.rb index f55876d..03f554e 100644 --- a/spec/factories/showback_pool.rb +++ b/spec/factories/showback_envelope.rb @@ -1,5 +1,5 @@ FactoryGirl.define do - factory :showback_pool, :class => ManageIQ::Consumption::ShowbackPool do + factory :showback_envelope, :class => ManageIQ::Consumption::ShowbackEnvelope do sequence(:name) { |n| "factory_pool_#{seq_padded_for_sorting(n)}" } sequence(:description) { |n| "pool_description_#{seq_padded_for_sorting(n)}" } start_time 4.hours.ago diff --git a/spec/factories/showback_input_measure.rb b/spec/factories/showback_input_measure.rb new file mode 100644 index 0000000..2cbd130 --- /dev/null +++ b/spec/factories/showback_input_measure.rb @@ -0,0 +1,8 @@ +FactoryGirl.define do + factory :showback_input_measure, :class => ManageIQ::Consumption::ShowbackInputMeasure do + entity 'Vm' + sequence(:description) { |s| "Description #{s}" } + group 'CPU' + fields ['average'] + end +end diff --git a/spec/factories/showback_rate.rb b/spec/factories/showback_rate.rb index 5f3d190..360a008 100644 --- a/spec/factories/showback_rate.rb +++ b/spec/factories/showback_rate.rb @@ -1,8 +1,8 @@ FactoryGirl.define do factory :showback_rate, :class => ManageIQ::Consumption::ShowbackRate do - category 'Vm' - dimension 'max_number_of_cpu' - measure 'CPU' + entity 'Vm' + field 'max_number_of_cpu' + group 'CPU' sequence(:concept) { |n| "Concept #{n}" } screener { {} } calculation 'duration' @@ -27,21 +27,21 @@ end end trait :CPU_average do - measure 'CPU' - dimension 'average' + group 'CPU' + field 'average' end trait :CPU_number do - measure 'CPU' - dimension 'number' + group 'CPU' + field 'number' end trait :CPU_max_number_of_cpu do - measure 'CPU' - dimension 'max_number_of_cpu' + group 'CPU' + field 'max_number_of_cpu' end trait :MEM_max_mem do - measure 'MEM' - dimension 'max_mem' + group 'MEM' + field 'max_mem' end end end diff --git a/spec/factories/showback_usage_type.rb b/spec/factories/showback_usage_type.rb deleted file mode 100644 index 3a63200..0000000 --- a/spec/factories/showback_usage_type.rb +++ /dev/null @@ -1,8 +0,0 @@ -FactoryGirl.define do - factory :showback_usage_type, :class => ManageIQ::Consumption::ShowbackUsageType do - category 'Vm' - sequence(:description) { |s| "Description #{s}" } - measure 'CPU' - dimensions ['average'] - end -end diff --git a/spec/models/consumption_manager_spec.rb b/spec/models/consumption_manager_spec.rb index 3dd21a4..a5a2c7f 100644 --- a/spec/models/consumption_manager_spec.rb +++ b/spec/models/consumption_manager_spec.rb @@ -16,50 +16,50 @@ it "generate new month for actual events" do vm = FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096)) - FactoryGirl.create(:showback_event, + FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month - 1.month, :end_time => DateTime.now.utc.end_of_month - 1.month, :resource => vm) - expect(ManageIQ::Consumption::ShowbackEvent.where(:resource =>vm).count).to eq(1) + expect(ManageIQ::Consumption::ShowbackDataRollup.where(:resource =>vm).count).to eq(1) described_class.generate_new_month - expect(ManageIQ::Consumption::ShowbackEvent.where(:resource =>vm).count).to eq(2) + expect(ManageIQ::Consumption::ShowbackDataRollup.where(:resource =>vm).count).to eq(2) end it "should generate events for new resources" do FactoryGirl.create(:vm) - expect(ManageIQ::Consumption::ShowbackEvent.all.count).to eq(0) + expect(ManageIQ::Consumption::ShowbackDataRollup.all.count).to eq(0) described_class.generate_events - expect(ManageIQ::Consumption::ShowbackEvent.all.count).to eq(1) - expect(ManageIQ::Consumption::ShowbackEvent.first.start_time.month).to eq(ManageIQ::Consumption::ShowbackEvent.first.end_time.month) + expect(ManageIQ::Consumption::ShowbackDataRollup.all.count).to eq(1) + expect(ManageIQ::Consumption::ShowbackDataRollup.first.start_time.month).to eq(ManageIQ::Consumption::ShowbackDataRollup.first.end_time.month) end it "should not generate the same ShowbackEvent 2 times of the same resource" do FactoryGirl.create(:vm) described_class.generate_events described_class.generate_events - expect(ManageIQ::Consumption::ShowbackEvent.all.count).to eq(1) + expect(ManageIQ::Consumption::ShowbackDataRollup.all.count).to eq(1) end it "should generate new Showbackevent of resource if not has an event for actual month" do vm = FactoryGirl.create(:vm) - FactoryGirl.create(:showback_event, + FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month - 1.month, :end_time => DateTime.now.utc.end_of_month - 1.month, :resource => vm) - count = ManageIQ::Consumption::ShowbackEvent.all.count + count = ManageIQ::Consumption::ShowbackDataRollup.all.count described_class.generate_events - expect(ManageIQ::Consumption::ShowbackEvent.all.count).to eq(count + 1) + expect(ManageIQ::Consumption::ShowbackDataRollup.all.count).to eq(count + 1) end it "should generate a showbackevent of service" do serv = FactoryGirl.create(:service) described_class.generate_events - expect(ManageIQ::Consumption::ShowbackEvent.first.resource).to eq(serv) - expect(ManageIQ::Consumption::ShowbackEvent.first.context).not_to be_nil + expect(ManageIQ::Consumption::ShowbackDataRollup.first.resource).to eq(serv) + expect(ManageIQ::Consumption::ShowbackDataRollup.first.context).not_to be_nil end it "should update the events" do - event_metric = FactoryGirl.create(:showback_event, :start_time => DateTime.now.utc.beginning_of_month, :end_time => DateTime.now.utc.beginning_of_month + 2.days) + event_metric = FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month, :end_time => DateTime.now.utc.beginning_of_month + 2.days) event_metric.data = { "CPU" => { "average" => [52.67, "percent"], @@ -95,7 +95,7 @@ event_metric.resource_id = @vm_metrics.id event_metric.resource_type = @vm_metrics.class.name event_metric.save! - new_average = (event_metric.get_measure_value("CPU", "average").to_d * event_metric.event_days + + new_average = (event_metric.get_group_value("CPU", "average").to_d * event_metric.event_days + event_metric.resource.metrics.for_time_range(event_metric.end_time, nil).average(:cpu_usage_rate_average)) / (event_metric.event_days + 1) data_new["CPU"]["average"][0] = new_average.to_s described_class.update_events @@ -104,18 +104,18 @@ expect(event_metric.end_time).to eq(@vm_metrics.metrics.last.timestamp) end - it "Make the seed of ShowbackUsageType and ShowbackPricePlan" do + it "Make the seed of ShowbackInputgroup and ShowbackPricePlan" do expect(ManageIQ::Consumption::ShowbackPricePlan).to receive(:seed) - expect(ManageIQ::Consumption::ShowbackUsageType).to receive(:seed) + expect(ManageIQ::Consumption::ShowbackInputMeasure).to receive(:seed) described_class.seed end context 'Units' do it "Should be the unit defined in YAML" do - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed data_units = ManageIQ::Consumption::ConsumptionManager.load_column_units - ManageIQ::Consumption::ShowbackUsageType.all.each do |usage| - usage.dimensions.each do |dim| + ManageIQ::Consumption::ShowbackInputMeasure.all.each do |usage| + usage.fields.each do |dim| expect(data_units).to include(dim.to_sym) end end diff --git a/spec/models/showback_event/cpu_spec.rb b/spec/models/showback_data_rollup/cpu_spec.rb similarity index 89% rename from spec/models/showback_event/cpu_spec.rb rename to spec/models/showback_data_rollup/cpu_spec.rb index 977528e..6f44d22 100644 --- a/spec/models/showback_event/cpu_spec.rb +++ b/spec/models/showback_data_rollup/cpu_spec.rb @@ -1,6 +1,6 @@ -describe ManageIQ::Consumption::ShowbackEvent::CPU do - let(:event) { FactoryGirl.build(:showback_event) } - let(:con_event) { FactoryGirl.build(:showback_event) } +describe ManageIQ::Consumption::ShowbackDataRollup::CPU do + let(:event) { FactoryGirl.build(:showback_data_rollup) } + let(:con_event) { FactoryGirl.build(:showback_data_rollup) } context "CPU in vm" do before(:each) do @vm_metrics = FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096)) @@ -24,8 +24,8 @@ event.resource = @vm_metrics event.start_time = "2010-04-13T00:00:00Z" event.end_time = "2010-04-14T00:00:00Z" - measure = FactoryGirl.build(:showback_usage_type) - measure.save + group = FactoryGirl.build(:showback_input_measure) + group.save event.generate_data end @@ -61,8 +61,8 @@ :image_tag_names => "environment/prod", :state_data => {:numvcpus => 2}) end - measure = FactoryGirl.build(:showback_usage_type) - measure.save + group = FactoryGirl.build(:showback_input_measure) + group.save event.generate_data end diff --git a/spec/models/showback_event/flavor_spec.rb b/spec/models/showback_data_rollup/flavor_spec.rb similarity index 94% rename from spec/models/showback_event/flavor_spec.rb rename to spec/models/showback_data_rollup/flavor_spec.rb index d43ad45..8bee36b 100644 --- a/spec/models/showback_event/flavor_spec.rb +++ b/spec/models/showback_data_rollup/flavor_spec.rb @@ -1,8 +1,8 @@ -describe ManageIQ::Consumption::ShowbackEvent::FLAVOR do - let(:event) { FactoryGirl.build(:showback_event) } +describe ManageIQ::Consumption::ShowbackDataRollup::FLAVOR do + let(:event) { FactoryGirl.build(:showback_data_rollup) } context "FLAVOR in vm" do before(:each) do - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed @vm_metrics = FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096)) cases = [ "2010-04-13T20:52:30Z", 100.0, @@ -24,8 +24,8 @@ event.resource = @vm_metrics event.start_time = "2010-04-13T00:00:00Z" event.end_time = "2010-04-14T00:00:00Z" - measure = FactoryGirl.build(:showback_usage_type) - measure.save + group = FactoryGirl.build(:showback_input_measure) + group.save event.generate_data end @@ -77,7 +77,7 @@ context "FLAVOR in container" do before(:each) do - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed @con_metrics = FactoryGirl.create(:container) event.resource = @con_metrics event.resource.type = "Container" @@ -89,8 +89,8 @@ :image_tag_names => "environment/prod", :state_data => {:numvcpus => 2, :total_mem => 4096}) end - measure = FactoryGirl.build(:showback_usage_type) - measure.save + group = FactoryGirl.build(:showback_input_measure) + group.save event.generate_data end diff --git a/spec/models/showback_event/mem_spec.rb b/spec/models/showback_data_rollup/mem_spec.rb similarity index 86% rename from spec/models/showback_event/mem_spec.rb rename to spec/models/showback_data_rollup/mem_spec.rb index 5680667..3a7e5bd 100644 --- a/spec/models/showback_event/mem_spec.rb +++ b/spec/models/showback_data_rollup/mem_spec.rb @@ -1,6 +1,6 @@ -describe ManageIQ::Consumption::ShowbackEvent::MEM do - let(:event) { FactoryGirl.build(:showback_event) } - let(:con_event) { FactoryGirl.build(:showback_event) } +describe ManageIQ::Consumption::ShowbackDataRollup::MEM do + let(:event) { FactoryGirl.build(:showback_data_rollup) } + let(:con_event) { FactoryGirl.build(:showback_data_rollup) } context "memory in vm" do before(:each) do @vm_metrics = FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096)) @@ -27,8 +27,8 @@ event.resource = @vm_metrics event.start_time = "2010-04-13T00:00:00Z" event.end_time = "2010-04-14T00:00:00Z" - measure = FactoryGirl.build(:showback_usage_type) - measure.save + group = FactoryGirl.build(:showback_input_measure) + group.save event.generate_data end @@ -51,8 +51,8 @@ :image_tag_names => "environment/prod", :state_data => {:total_mem => 1024}) end - measure = FactoryGirl.build(:showback_usage_type) - measure.save + group = FactoryGirl.build(:showback_input_measure) + group.save event.generate_data end diff --git a/spec/models/showback_event_spec.rb b/spec/models/showback_data_rollup_spec.rb similarity index 63% rename from spec/models/showback_event_spec.rb rename to spec/models/showback_data_rollup_spec.rb index fa30682..93a2ac4 100644 --- a/spec/models/showback_event_spec.rb +++ b/spec/models/showback_data_rollup_spec.rb @@ -1,79 +1,79 @@ require 'spec_helper' require 'money-rails/test_helpers' -describe ManageIQ::Consumption::ShowbackEvent do - let(:showback_event) { FactoryGirl.build(:showback_event) } +describe ManageIQ::Consumption::ShowbackDataRollup do + let(:data_rollup) { FactoryGirl.build(:showback_data_rollup) } context "validations" do it "has a valid factory" do - expect(showback_event).to be_valid + expect(data_rollup).to be_valid end it "should ensure presence of start_time" do - showback_event.start_time = nil - showback_event.valid? - expect(showback_event.errors[:start_time]).to include "can't be blank" + data_rollup.start_time = nil + data_rollup.valid? + expect(data_rollup.errors[:start_time]).to include "can't be blank" end it "should ensure presence of end_time" do - showback_event.end_time = nil - showback_event.valid? - expect(showback_event.errors[:end_time]).to include "can't be blank" + data_rollup.end_time = nil + data_rollup.valid? + expect(data_rollup.errors[:end_time]).to include "can't be blank" end it "should fails start time is after of end time" do - showback_event.start_time = 1.hour.ago - showback_event.end_time = 4.hours.ago - showback_event.valid? - expect(showback_event.errors[:start_time]).to include "Start time should be before end time" + data_rollup.start_time = 1.hour.ago + data_rollup.end_time = 4.hours.ago + data_rollup.valid? + expect(data_rollup.errors[:start_time]).to include "Start time should be before end time" end it "should valid if start time is equal to end time" do - showback_event.start_time = 1.hour.ago - showback_event.end_time = showback_event.start_time - expect(showback_event).to be_valid + data_rollup.start_time = 1.hour.ago + data_rollup.end_time = data_rollup.start_time + expect(data_rollup).to be_valid end it "should ensure presence of resource" do - showback_event.resource = nil - expect(showback_event).not_to be_valid + data_rollup.resource = nil + expect(data_rollup).not_to be_valid end it "should ensure resource exists" do vm = FactoryGirl.create(:vm) - showback_event.resource = vm - expect(showback_event).to be_valid + data_rollup.resource = vm + expect(data_rollup).to be_valid end it 'should generate data' do - showback_event.data = {} - showback_event.resource = FactoryGirl.create(:vm) + data_rollup.data = {} + data_rollup.resource = FactoryGirl.create(:vm) hash = {} - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed data_units = ManageIQ::Consumption::ConsumptionManager.load_column_units - ManageIQ::Consumption::ShowbackUsageType.all.each do |measure_type| - next unless showback_event.resource.type.ends_with?(measure_type.category) - hash[measure_type.measure] = {} - measure_type.dimensions.each do |dim| - hash[measure_type.measure][dim] = [0, data_units[dim.to_sym] || ""] unless measure_type.measure == "FLAVOR" + ManageIQ::Consumption::ShowbackInputMeasure.all.each do |group_type| + next unless data_rollup.resource.type.ends_with?(group_type.entity) + hash[group_type.group] = {} + group_type.fields.each do |dim| + hash[group_type.group][dim] = [0, data_units[dim.to_sym] || ""] unless group_type.group == "FLAVOR" end end - showback_event.generate_data - expect(showback_event.data).to eq(hash) - expect(showback_event.data).not_to be_empty - expect(showback_event.start_time).not_to eq("") + data_rollup.generate_data + expect(data_rollup.data).to eq(hash) + expect(data_rollup.data).not_to be_empty + expect(data_rollup.start_time).not_to eq("") end it "should clean data " do - showback_event.data = { "cores" => 2} - expect(showback_event.data).not_to be_empty - showback_event.clean_data - expect(showback_event.data).to be_empty + data_rollup.data = { "cores" => 2} + expect(data_rollup.data).not_to be_empty + data_rollup.clean_data + expect(data_rollup.data).to be_empty end end context '#flavor functions' do it 'should return last flavor' do - showback_event.data = { + data_rollup.data = { "FLAVOR" => { 1_501_545_600 => {"cores" => 4, "memory" => 16}, 1_501_632_000 => {"cores" => 8, "memory" => 32}, @@ -82,25 +82,25 @@ } } - expect(showback_event.last_flavor).to eq("cores" => 4, "memory" => 16) - expect(showback_event.get_key_flavor("cores")).to eq(4) - expect(showback_event.get_key_flavor("memory")).to eq(16) + expect(data_rollup.last_flavor).to eq("cores" => 4, "memory" => 16) + expect(data_rollup.get_key_flavor("cores")).to eq(4) + expect(data_rollup.get_key_flavor("memory")).to eq(16) end end context '#validate_format' do it 'passes validation with correct JSON data' do - event = FactoryGirl.create(:showback_event) + event = FactoryGirl.create(:showback_data_rollup) expect(event.validate_format).to be_nil end it 'fails validations with incorrect JSON data' do - event = FactoryGirl.build(:showback_event, :data => ":-Invalid:\n-JSON") + event = FactoryGirl.build(:showback_data_rollup, :data => ":-Invalid:\n-JSON") expect(event.validate_format).to be_nil end it 'returns nil if ParserError' do - event = FactoryGirl.create(:showback_event) + event = FactoryGirl.create(:showback_data_rollup) event.data = "abc" expect(event.validate_format).to be_nil end @@ -108,15 +108,15 @@ context '#engine' do let(:vm) { FactoryGirl.create(:vm) } - let(:event) { FactoryGirl.build(:showback_event, :full_month) } - let(:vm_event) { FactoryGirl.build(:showback_event, :with_vm_data, :first_half_month) } + let(:event) { FactoryGirl.build(:showback_data_rollup, :full_month) } + let(:vm_event) { FactoryGirl.build(:showback_data_rollup, :with_vm_data, :first_half_month) } describe 'Basic' do it 'should return the object' do event.resource = vm expect(event.resource).to eq(vm) end it 'trait #full_month should have a valid factory' do - myevent = FactoryGirl.build(:showback_event, :full_month) + myevent = FactoryGirl.build(:showback_data_rollup, :full_month) myevent.valid? expect(myevent).to be_valid expect(myevent.start_time).to eq(myevent.start_time.beginning_of_month) @@ -124,7 +124,7 @@ end it 'trait #with_vm_data should have a valid factory' do - myevent = FactoryGirl.build(:showback_event, :with_vm_data) + myevent = FactoryGirl.build(:showback_data_rollup, :with_vm_data) myevent.valid? expect(myevent.data).to eq( "CPU" => { @@ -141,7 +141,7 @@ end it 'trait #first_half_month should have a valid factory' do - myevent = FactoryGirl.build(:showback_event, :first_half_month) + myevent = FactoryGirl.build(:showback_data_rollup, :first_half_month) myevent.valid? expect(myevent).to be_valid expect(myevent.start_time).to eq(myevent.start_time.beginning_of_month) @@ -149,7 +149,7 @@ end it 'trait #with_vm_datra and full_month has a valid factory' do - myevent = FactoryGirl.build(:showback_event, :with_vm_data, :full_month) + myevent = FactoryGirl.build(:showback_data_rollup, :with_vm_data, :full_month) myevent.valid? expect(myevent).to be_valid expect(myevent.start_time).to eq(myevent.start_time.beginning_of_month) @@ -168,7 +168,7 @@ end it 'trait #with_vm_datra and half_month has a valid factory' do - myevent = FactoryGirl.build(:showback_event, :with_vm_data, :first_half_month) + myevent = FactoryGirl.build(:showback_data_rollup, :with_vm_data, :first_half_month) myevent.valid? expect(myevent).to be_valid expect(myevent.start_time).to eq(myevent.start_time.beginning_of_month) @@ -212,41 +212,41 @@ event.resource = @vm_metrics event.start_time = "2010-04-13T00:00:00Z" event.end_time = "2010-04-14T00:00:00Z" - measure = FactoryGirl.build(:showback_usage_type) - measure.save + group = FactoryGirl.build(:showback_input_measure) + group.save end - it 'should return value of the measure with dimension' do + it 'should return value of the group with field' do event.data = { 'CPU' => { 'average' => [event.resource.metrics.for_time_range(event.start_time, event.end_time).average(:cpu_usage_rate_average), "percent"] } } expect(event.start_time.month).to eq(event.end_time.month) - expect(event.get_measure('CPU', 'average')).to eq([event.resource.metrics.for_time_range(event.start_time, event.end_time).average(:cpu_usage_rate_average).to_s, "percent"]) + expect(event.get_group('CPU', 'average')).to eq([event.resource.metrics.for_time_range(event.start_time, event.end_time).average(:cpu_usage_rate_average).to_s, "percent"]) end - it 'return nil if dimension is not found' do + it 'return nil if field is not found' do event.data = { 'CPU' => { 'average' => [event.resource.metrics.for_time_range(event.start_time, event.end_time).average(:cpu_usage_rate_average), "percent"] } } - expect(event.get_measure('CPU', 'not there')).to be_nil + expect(event.get_group('CPU', 'not there')).to be_nil end - it 'return nil if category is not found' do + it 'return nil if entity is not found' do event.data = { 'CPU' => { 'average' => [event.resource.metrics.for_time_range(event.start_time, event.end_time).average(:cpu_usage_rate_average), "percent"] } } - expect(event.get_measure('not there', 'average')).to be_nil + expect(event.get_group('not there', 'average')).to be_nil end it 'should return [value,unit]n' do event.data = {"CPU" => { "average" => [52.67, "percent"]}} - expect(event.get_measure('CPU', 'average')).to eq([52.67, "percent"]) + expect(event.get_group('CPU', 'average')).to eq([52.67, "percent"]) end it 'should return metrics time range' do @@ -262,15 +262,15 @@ end it 'should return events of past month' do - 5.times { FactoryGirl.create(:showback_event, :full_month) } - 2.times { FactoryGirl.create(:showback_event, :start_time => DateTime.now.utc.beginning_of_month - 1.month, :end_time => DateTime.now.utc.end_of_month - 1.month) } + 5.times { FactoryGirl.create(:showback_data_rollup, :full_month) } + 2.times { FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month - 1.month, :end_time => DateTime.now.utc.end_of_month - 1.month) } expect(described_class.events_past_month.count).to eq(2) end it 'should return events of actual month' do - 5.times { FactoryGirl.create(:showback_event, :full_month) } + 5.times { FactoryGirl.create(:showback_data_rollup, :full_month) } 2.times do - FactoryGirl.create(:showback_event, + FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month - 1.month, :end_time => DateTime.now.utc.end_of_month - 1.month) end @@ -279,12 +279,12 @@ it 'should return events between months' do 3.times do - FactoryGirl.create(:showback_event, + FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month.change(:month =>2), :end_time => DateTime.now.utc.end_of_month.change(:month =>2)) end 2.times do - FactoryGirl.create(:showback_event, + FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month.change(:month =>4), :end_time => DateTime.now.utc.end_of_month.change(:month =>4)) end @@ -306,7 +306,7 @@ "average" => [event.resource.metrics.for_time_range(event.start_time, event.end_time).average(:cpu_usage_rate_average), "percent"] } } - new_average = (event.get_measure_value("CPU", "average").to_d * event.event_days + + new_average = (event.get_group_value("CPU", "average").to_d * event.event_days + event.resource.metrics.for_time_range(event.end_time, nil).average(:cpu_usage_rate_average)) / (event.event_days + 1) event.update_event expect(event.start_time.month).to eq(event.end_time.month) @@ -324,129 +324,116 @@ } event.update_event expect(event.start_time.month).to eq(event.end_time.month) - expect(event.get_measure("CPU", "max_number_of_cpu")).to eq([3, "cores"]) + expect(event.get_group("CPU", "max_number_of_cpu")).to eq([3, "cores"]) end end context 'assign event to pool' do it "Return nil if not pool" do vm = FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096)) - FactoryGirl.create(:showback_pool, :resource => FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096))) + FactoryGirl.create(:showback_envelope, :resource => FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096))) expect(event.find_pool(vm)).to be_nil end it "Return the correct pool" do vm = FactoryGirl.create(:vm, :hardware => FactoryGirl.create(:hardware, :cpu1x2, :memory_mb => 4096)) - pool = FactoryGirl.create(:showback_pool, :resource => vm) + pool = FactoryGirl.create(:showback_envelope, :resource => vm) expect(event.find_pool(vm)).to eq(pool) end it "Should return value of CPU data" do event.data = {"CPU" => { "average" => [52.67, "percent"]}} - expect(event.get_measure_value('CPU', 'average')).to eq(52.67) + expect(event.get_group_value('CPU', 'average')).to eq(52.67) end it "Should return unit of CPU data" do event.data = {"CPU" => { "average" => [52.67, "percent"]}} - expect(event.get_measure_unit('CPU', 'average')).to eq("percent") + expect(event.get_group_unit('CPU', 'average')).to eq("percent") end it "Assign resource to pool" do vm = FactoryGirl.create(:vm) - pool = FactoryGirl.create(:showback_pool, :resource => vm) - event = FactoryGirl.create(:showback_event, + pool = FactoryGirl.create(:showback_envelope, :resource => vm) + event = FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month, :end_time => DateTime.now.utc.beginning_of_month + 2.days, :resource => vm) - expect(pool.showback_events.count).to eq(0) + expect(pool.showback_data_rollups.count).to eq(0) event.assign_resource - expect(pool.showback_events.count).to eq(1) - expect(pool.showback_events.include?(event)).to be_truthy + expect(pool.showback_data_rollups.count).to eq(1) + expect(pool.showback_data_rollups.include?(event)).to be_truthy end it "Assign container resource to pool" do con = FactoryGirl.create(:container) con.type = "Container" - pool = FactoryGirl.create(:showback_pool, :resource => con) - event = FactoryGirl.create(:showback_event, + pool = FactoryGirl.create(:showback_envelope, :resource => con) + event = FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month, :end_time => DateTime.now.utc.beginning_of_month + 2.days, :resource => con) - expect(pool.showback_events.count).to eq(0) + expect(pool.showback_data_rollups.count).to eq(0) event.assign_resource - expect(pool.showback_events.count).to eq(1) - expect(pool.showback_events.include?(event)).to be_truthy + expect(pool.showback_data_rollups.count).to eq(1) + expect(pool.showback_data_rollups.include?(event)).to be_truthy end it "Assign resource to all relational pool" do host = FactoryGirl.create(:host) vm = FactoryGirl.create(:vm, :host => host) - pool_vm = FactoryGirl.create(:showback_pool, :resource => vm) - pool_host = FactoryGirl.create(:showback_pool, :resource => host) - event = FactoryGirl.create(:showback_event, + pool_vm = FactoryGirl.create(:showback_envelope, :resource => vm) + pool_host = FactoryGirl.create(:showback_envelope, :resource => host) + event = FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month, :end_time => DateTime.now.utc.beginning_of_month + 2.days, :resource => vm) event.assign_resource - expect(pool_vm.showback_events.include?(event)).to be_truthy - expect(pool_host.showback_events.include?(event)).to be_truthy + expect(pool_vm.showback_data_rollups.include?(event)).to be_truthy + expect(pool_host.showback_data_rollups.include?(event)).to be_truthy end +=begin it "Assign a pool tag" do - @file = StringIO.new("name,category,entry\nJD-C-T4.0.1.44,Environment,Test") + @file = StringIO.new("name,entity,entry\nJD-C-T4.0.1.44,Environment,Test") vm = FactoryGirl.create(:vm, :name => "JD-C-T4.0.1.44") - event = FactoryGirl.create(:showback_event, + event = FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month, :end_time => DateTime.now.utc.beginning_of_month + 2.days, :resource => vm) - category = FactoryGirl.create(:classification, :name => 'environment', :description => 'Environment') - entry = FactoryGirl.create(:classification, :parent_id => category.id, :name => 'test', :description => 'Test') - pool_cat = FactoryGirl.create(:showback_pool, :resource => category.tag) - pool_ent = FactoryGirl.create(:showback_pool, :resource => entry.tag) + entity = FactoryGirl.create(:classification, :name => 'environment', :description => 'Environment') + entry = FactoryGirl.create(:classification, :parent_id => entity.id, :name => 'test', :description => 'Test') + pool_cat = FactoryGirl.create(:showback_envelope, :resource => entity.tag) + pool_ent = FactoryGirl.create(:showback_envelope, :resource => entry.tag) ci = ClassificationImport.upload(@file) ci.apply vm.reload event.collect_tags + expect(event.context).to eq("tag" => {"environment" => ["test"]}) event.assign_by_tag - expect(pool_ent.showback_events.include?(event)).to be_truthy - expect(pool_cat.showback_events.include?(event)).to be_truthy + expect(pool_ent.showback_data_rollups.include?(event)).to be_truthy + expect(pool_cat.showback_data_rollups.include?(event)).to be_truthy end +=end end context 'collect tags' do it "Set an empty tags in context" do vm = FactoryGirl.create(:vm) - event = FactoryGirl.create(:showback_event, + event = FactoryGirl.create(:showback_data_rollup, :start_time => DateTime.now.utc.beginning_of_month, :end_time => DateTime.now.utc.beginning_of_month + 2.days, :resource => vm) event.collect_tags expect(event.context).to eq("tag" => {}) end - - it "Set a tags in context" do - @file = StringIO.new("name,category,entry\nJD-C-T4.0.1.44,Environment,Test") - vm = FactoryGirl.create(:vm, :name => "JD-C-T4.0.1.44") - event = FactoryGirl.create(:showback_event, - :start_time => DateTime.now.utc.beginning_of_month, - :end_time => DateTime.now.utc.beginning_of_month + 2.days, - :resource => vm) - category = FactoryGirl.create(:classification, :name => 'environment', :description => 'Environment') - FactoryGirl.create(:classification, :parent_id => category.id, :name => 'test', :description => 'Test') - ci = ClassificationImport.upload(@file) - ci.apply - vm.reload - event.collect_tags - expect(event.context).to eq("tag" => {"environment" => ["test"]}) - end end end context 'update charges' do - let(:event_to_charge) { FactoryGirl.create(:showback_event) } + let(:event_to_charge) { FactoryGirl.create(:showback_data_rollup) } let(:pool_of_event) do - FactoryGirl.create(:showback_pool, + FactoryGirl.create(:showback_envelope, :resource => event_to_charge.resource) end @@ -463,11 +450,11 @@ "FLAVOR" => {} } event_to_charge.save - charge1 = FactoryGirl.create(:showback_charge, - :showback_pool => pool_of_event, - :showback_event => event_to_charge, - :stored_data => {Time.now.utc - 5.hours => event_to_charge.data}) - data1 = charge1.stored_data_last + charge1 = FactoryGirl.create(:showback_data_view, + :showback_envelope => pool_of_event, + :showback_data_rollup => event_to_charge, + :data_snapshot => {Time.now.utc - 5.hours => event_to_charge.data}) + data1 = charge1.data_snapshot_last event_to_charge.data = { "CPU" => { "average" => [49.8571428571429, "percent"], @@ -482,7 +469,7 @@ event_to_charge.save event_to_charge.update_charges charge1.reload - expect(charge1.stored_data_last).not_to eq(data1) + expect(charge1.data_snapshot_last).not_to eq(data1) end end end diff --git a/spec/models/showback_charge_spec.rb b/spec/models/showback_data_view_spec.rb similarity index 70% rename from spec/models/showback_charge_spec.rb rename to spec/models/showback_data_view_spec.rb index 260731a..e907bb8 100644 --- a/spec/models/showback_charge_spec.rb +++ b/spec/models/showback_data_view_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' require 'money-rails/test_helpers' -RSpec.describe ManageIQ::Consumption::ShowbackCharge, :type => :model do +RSpec.describe ManageIQ::Consumption::ShowbackDataView, :type => :model do before(:each) do - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed end context 'basic life cycle' do - let(:charge) { FactoryGirl.build(:showback_charge) } + let(:charge) { FactoryGirl.build(:showback_data_view) } let(:cost) { Money.new(1) } it 'has a valid factory' do @@ -52,14 +52,14 @@ context '#validate price_plan_missing and snapshot' do let(:event) do - FactoryGirl.build(:showback_event, + FactoryGirl.build(:showback_data_rollup, :with_vm_data, :full_month) end let(:charge) do - FactoryGirl.build(:showback_charge, - :showback_event => event) + FactoryGirl.build(:showback_data_view, + :showback_data_rollup => event) end it "fails if can't find a price plan" do @@ -73,42 +73,42 @@ it "fails if snapshot of charge is not the event data after create" do event.save charge.save - expect(charge.stored_data.first[1]).to eq(event.data) + expect(charge.data_snapshot.first[1]).to eq(event.data) event.data = {"CPU" => {"average" => [2, "percent"], "max_number_of_cpu" => [40, "cores"]}} event.save charge.save - expect(charge.stored_data.first[1]).not_to eq(event.data) + expect(charge.data_snapshot.first[1]).not_to eq(event.data) end it "Return the stored data at start" do event.save charge.save - expect(charge.stored_data_start).to eq(event.data) + expect(charge.data_snapshot_start).to eq(event.data) end it "Return the last stored data" do event.save charge.save - expect(charge.stored_data.length).to eq(1) + expect(charge.data_snapshot.length).to eq(1) event.data = {"CPU" => {"average" => [2, "percent"], "max_number_of_cpu" => [40, "cores"]}} - charge.update_stored_data - expect(charge.stored_data_last).to eq(event.data) + charge.update_data_snapshot + expect(charge.data_snapshot_last).to eq(event.data) end it "Return the last stored data key" do event.save - charge.stored_data = { 3.hours.ago => {"CPU" => {"average" => [2, "percent"], "max_number_of_cpu" => [40, "cores"]}}, - Time.now.utc => {"CPU" => {"average" => [2, "percent"], "max_number_of_cpu" => [40, "cores"]}}} - t = charge.stored_data.keys.sort.last - expect(charge.stored_data_last_key).to eq(t) + charge.data_snapshot = { 3.hours.ago => {"CPU" => {"average" => [2, "percent"], "max_number_of_cpu" => [40, "cores"]}}, + Time.now.utc => {"CPU" => {"average" => [2, "percent"], "max_number_of_cpu" => [40, "cores"]}}} + t = charge.data_snapshot.keys.sort.last + expect(charge.data_snapshot_last_key).to eq(t) end end context '#stored data' do - let(:charge_data) { FactoryGirl.build(:showback_charge, :with_stored_data) } - let(:event_for_charge) { FactoryGirl.create(:showback_event) } + let(:charge_data) { FactoryGirl.build(:showback_data_view, :with_data_snapshot) } + let(:event_for_charge) { FactoryGirl.create(:showback_data_rollup) } let(:pool_of_event) do - FactoryGirl.create(:showback_pool, + FactoryGirl.create(:showback_envelope, :resource => event_for_charge.resource) end @@ -124,29 +124,29 @@ }, "FLAVOR" => {} } - charge1 = FactoryGirl.create(:showback_charge, - :showback_pool => pool_of_event, - :showback_event => event_for_charge) - expect(charge1.stored_data_start).to eq(event_for_charge.data) - charge1.stored_data_event - expect(charge1.stored_data_start).to eq(event_for_charge.data) + charge1 = FactoryGirl.create(:showback_data_view, + :showback_envelope => pool_of_event, + :showback_data_rollup => event_for_charge) + expect(charge1.data_snapshot_start).to eq(event_for_charge.data) + charge1.snapshot_event + expect(charge1.data_snapshot_start).to eq(event_for_charge.data) end - it "get measure" do - expect(charge_data.get_measure("CPU", "number")).to eq([2.0, "cores"]) + it "get group" do + expect(charge_data.get_group("CPU", "number")).to eq([2.0, "cores"]) end - it "get last measure" do - expect(charge_data.get_last_measure("CPU", "number")).to eq([4.0, "cores"]) + it "get last group" do + expect(charge_data.get_last_group("CPU", "number")).to eq([4.0, "cores"]) end - it "get pool measure" do - expect(charge_data.get_pool_measure("CPU", "number")).to eq([[2.0, "cores"], [4.0, "cores"]]) + it "get pool group" do + expect(charge_data.get_pool_group("CPU", "number")).to eq([[2.0, "cores"], [4.0, "cores"]]) end end context '#calculate_cost' do let(:cost) { Money.new(32) } - let(:pool) { FactoryGirl.create(:showback_pool) } + let(:pool) { FactoryGirl.create(:showback_envelope) } let!(:plan) { FactoryGirl.create(:showback_price_plan) } # By default is :enterprise let(:plan2) { FactoryGirl.create(:showback_price_plan) } let(:fixed_rate1) { Money.new(3) } @@ -166,16 +166,16 @@ end let(:showback_tier2) { rate2.showback_tiers.first } let(:event) do - FactoryGirl.create(:showback_event, + FactoryGirl.create(:showback_data_rollup, :with_vm_data, :full_month) end let(:charge) do - FactoryGirl.create(:showback_charge, - :showback_pool => pool, - :cost => cost, - :showback_event => event) + FactoryGirl.create(:showback_data_view, + :showback_envelope => pool, + :cost => cost, + :showback_data_rollup => event) end context 'without price_plan' do @@ -190,7 +190,7 @@ showback_tier1.save expect(event.data).not_to be_nil # making sure that the default is not empty expect(ManageIQ::Consumption::ShowbackPricePlan.count).to eq(1) - expect(charge.showback_event).to eq(event) + expect(charge.showback_data_rollup).to eq(event) expect(charge.calculate_cost).to eq(fixed_rate1 + variable_rate1 * event.data['CPU']['average'].first) end end @@ -213,11 +213,11 @@ expect(event.data).not_to be_nil plan2.reload expect(ManageIQ::Consumption::ShowbackPricePlan.count).to eq(2) - expect(charge.showback_event).to eq(event) + expect(charge.showback_data_rollup).to eq(event) # Test that it works without a plan - expect(charge.calculate_cost).to eq(fixed_rate1 + variable_rate1 * event.get_measure_value('CPU', 'average')) + expect(charge.calculate_cost).to eq(fixed_rate1 + variable_rate1 * event.get_group_value('CPU', 'average')) # Test that it changes if you provide a plan - expect(charge.calculate_cost(plan2)).to eq(fixed_rate2 + variable_rate2 * event.get_measure_value('CPU', 'average')) + expect(charge.calculate_cost(plan2)).to eq(fixed_rate2 + variable_rate2 * event.get_group_value('CPU', 'average')) end it 'raises an error if the plan provider is not working' do @@ -237,9 +237,9 @@ showback_tier2.save expect(event.data).not_to be_nil expect(ManageIQ::Consumption::ShowbackPricePlan.count).to eq(2) - expect(charge.showback_event).to eq(event) + expect(charge.showback_data_rollup).to eq(event) # Test that it works without a plan - expect(charge.calculate_cost).to eq(fixed_rate1 + variable_rate1 * event.get_measure_value('CPU', 'average')) + expect(charge.calculate_cost).to eq(fixed_rate1 + variable_rate1 * event.get_group_value('CPU', 'average')) # Test that it changes if you provide a plan expect(charge.calculate_cost('ERROR')).to eq(Money.new(0)) expect(charge.errors.details[:showback_price_plan]).to include(:error => 'not found') diff --git a/spec/models/showback_pool_spec.rb b/spec/models/showback_envelope_spec.rb similarity index 68% rename from spec/models/showback_pool_spec.rb rename to spec/models/showback_envelope_spec.rb index 19d3d1d..fc9a8b7 100644 --- a/spec/models/showback_pool_spec.rb +++ b/spec/models/showback_envelope_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' require 'money-rails/test_helpers' -RSpec.describe ManageIQ::Consumption::ShowbackPool, :type => :model do +RSpec.describe ManageIQ::Consumption::ShowbackEnvelope, :type => :model do before(:each) do - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed end let(:resource) { FactoryGirl.create(:vm) } - let(:pool) { FactoryGirl.build(:showback_pool) } - let(:event) { FactoryGirl.build(:showback_event, :with_vm_data, :full_month, :resource => resource) } - let(:event2) { FactoryGirl.build(:showback_event, :with_vm_data, :full_month, :resource => resource) } + let(:pool) { FactoryGirl.build(:showback_envelope) } + let(:event) { FactoryGirl.build(:showback_data_rollup, :with_vm_data, :full_month, :resource => resource) } + let(:event2) { FactoryGirl.build(:showback_data_rollup, :with_vm_data, :full_month, :resource => resource) } let(:enterprise_plan) { FactoryGirl.create(:showback_price_plan) } context '#basic lifecycle' do @@ -36,26 +36,26 @@ end it 'monetizes accumulated cost' do - expect(ManageIQ::Consumption::ShowbackPool).to monetize(:accumulated_cost) + expect(ManageIQ::Consumption::ShowbackEnvelope).to monetize(:accumulated_cost) end it 'deletes costs associated when deleting the pool' do 2.times do - FactoryGirl.create(:showback_charge, :showback_pool => pool) + FactoryGirl.create(:showback_data_view, :showback_envelope => pool) end - expect(pool.showback_charges.count).to be(2) - expect { pool.destroy }.to change(ManageIQ::Consumption::ShowbackCharge, :count).from(2).to(0) - expect(pool.showback_charges.count).to be(0) + expect(pool.showback_data_views.count).to be(2) + expect { pool.destroy }.to change(ManageIQ::Consumption::ShowbackDataView, :count).from(2).to(0) + expect(pool.showback_data_views.count).to be(0) end it 'deletes costs associated when deleting the event' do 2.times do - FactoryGirl.create(:showback_charge, :showback_pool => pool) + FactoryGirl.create(:showback_data_view, :showback_envelope => pool) end - expect(pool.showback_charges.count).to be(2) - event = pool.showback_charges.first.showback_event - expect { event.destroy }.to change(ManageIQ::Consumption::ShowbackCharge, :count).from(2).to(1) - expect(pool.showback_events).not_to include(event) + expect(pool.showback_data_views.count).to be(2) + event = pool.showback_data_views.first.showback_data_rollup + expect { event.destroy }.to change(ManageIQ::Consumption::ShowbackDataView, :count).from(2).to(1) + expect(pool.showback_data_rollups).not_to include(event) end it 'it only can be in approved states' do @@ -80,7 +80,7 @@ end context '.control lifecycle state' do - let(:pool_lifecycle) { FactoryGirl.create(:showback_pool) } + let(:pool_lifecycle) { FactoryGirl.create(:showback_envelope) } it 'it can transition from open to processing' do pool_lifecycle.state = 'PROCESSING' @@ -102,22 +102,22 @@ end it 'it can not transition from processing to open' do - pool_lifecycle = FactoryGirl.create(:showback_pool, :processing) + pool_lifecycle = FactoryGirl.create(:showback_envelope, :processing) pool_lifecycle.state = 'OPEN' expect { pool_lifecycle.save }.to raise_error(RuntimeError, _("Pool can't change state to OPEN from PROCESSING")) end it 'it can transition from processing to closed' do - pool_lifecycle = FactoryGirl.create(:showback_pool, :processing) + pool_lifecycle = FactoryGirl.create(:showback_envelope, :processing) pool_lifecycle.state = 'CLOSED' expect { pool_lifecycle.save }.not_to raise_error end it 'it can not transition from closed to open or processing' do - pool_lifecycle = FactoryGirl.create(:showback_pool, :closed) + pool_lifecycle = FactoryGirl.create(:showback_envelope, :closed) pool_lifecycle.state = 'OPEN' expect { pool_lifecycle.save }.to raise_error(RuntimeError, _("Pool can't change state when it's CLOSED")) - pool_lifecycle = FactoryGirl.create(:showback_pool, :closed) + pool_lifecycle = FactoryGirl.create(:showback_envelope, :closed) pool_lifecycle.state = 'PROCESSING' expect { pool_lifecycle.save }.to raise_error(RuntimeError, _("Pool can't change state when it's CLOSED")) end @@ -127,72 +127,72 @@ describe 'methods for events' do it 'can add an event to a pool' do - expect { pool.add_event(event) }.to change(pool.showback_events, :count).by(1) - expect(pool.showback_events).to include(event) + expect { pool.add_event(event) }.to change(pool.showback_data_rollups, :count).by(1) + expect(pool.showback_data_rollups).to include(event) end it 'throws an error for duplicate events when using Add event to a Pool' do pool.add_event(event) pool.add_event(event) - expect(pool.errors.details[:showback_events]). to include(:error => "duplicate") + expect(pool.errors.details[:showback_data_rollups]). to include(:error => "duplicate") end it 'Throw error in add event if it is not of a proper type' do obj = FactoryGirl.create(:vm) pool.add_event(obj) - expect(pool.errors.details[:showback_events]). to include(:error => "Error Type #{obj.type} is not ManageIQ::Consumption::ShowbackEvent") + expect(pool.errors.details[:showback_data_rollups]). to include(:error => "Error Type #{obj.type} is not ManageIQ::Consumption::ShowbackEvent") end it 'Remove event from a Pool' do pool.add_event(event) - expect { pool.remove_event(event) }.to change(pool.showback_events, :count).by(-1) - expect(pool.showback_events).not_to include(event) + expect { pool.remove_event(event) }.to change(pool.showback_data_rollups, :count).by(-1) + expect(pool.showback_data_rollups).not_to include(event) end it 'Throw error in Remove event from a Pool if the event can not be found' do pool.add_event(event) pool.remove_event(event) pool.remove_event(event) - expect(pool.errors.details[:showback_events]). to include(:error => "not found") + expect(pool.errors.details[:showback_data_rollups]). to include(:error => "not found") end it 'Throw error in Remove event if the type is not correct' do obj = FactoryGirl.create(:vm) pool.remove_event(obj) - expect(pool.errors.details[:showback_events]). to include(:error => "Error Type #{obj.type} is not ManageIQ::Consumption::ShowbackEvent") + expect(pool.errors.details[:showback_data_rollups]). to include(:error => "Error Type #{obj.type} is not ManageIQ::Consumption::ShowbackEvent") end end - describe 'methods with #showback_charge' do + describe 'methods with #showback_data_view' do it 'add charge directly' do - charge = FactoryGirl.create(:showback_charge, :showback_pool => pool) + charge = FactoryGirl.create(:showback_data_view, :showback_envelope => pool) pool.add_charge(charge, 2) expect(charge.cost). to eq(Money.new(2)) end it 'add charge directly' do - charge = FactoryGirl.create(:showback_charge, :cost => Money.new(7)) # different pool + charge = FactoryGirl.create(:showback_data_view, :cost => Money.new(7)) # different pool pool.add_charge(charge, 2) # Charge won't be updated as it does not belongs to the pool expect(charge.cost).not_to eq(Money.new(2)) - expect(charge.showback_pool).not_to eq(pool) + expect(charge.showback_envelope).not_to eq(pool) end it 'add charge from an event' do - event = FactoryGirl.create(:showback_event) - charge = FactoryGirl.create(:showback_charge, :showback_event => event, :showback_pool => pool) - expect(event.showback_charges).to include(charge) - expect(pool.showback_charges).to include(charge) + event = FactoryGirl.create(:showback_data_rollup) + charge = FactoryGirl.create(:showback_data_view, :showback_data_rollup => event, :showback_envelope => pool) + expect(event.showback_data_views).to include(charge) + expect(pool.showback_data_views).to include(charge) end it 'get_charge from a charge' do - charge = FactoryGirl.create(:showback_charge, :showback_pool => pool, :cost => Money.new(10)) + charge = FactoryGirl.create(:showback_data_view, :showback_envelope => pool, :cost => Money.new(10)) expect(pool.get_charge(charge)).to eq(Money.new(10)) end it 'get_charge from an event' do - charge = FactoryGirl.create(:showback_charge, :showback_pool => pool, :cost => Money.new(10)) - event = charge.showback_event + charge = FactoryGirl.create(:showback_data_view, :showback_envelope => pool, :cost => Money.new(10)) + event = charge.showback_data_rollup expect(pool.get_charge(event)).to eq(Money.new(10)) end @@ -201,9 +201,9 @@ end it 'calculate_charge with an error' do - charge = FactoryGirl.create(:showback_charge, :cost => Money.new(10)) + charge = FactoryGirl.create(:showback_data_view, :cost => Money.new(10)) pool.calculate_charge(charge) - expect(charge.errors.details[:showback_charge]). to include(:error => 'not found') + expect(charge.errors.details[:showback_data_view]). to include(:error => 'not found') expect(pool.calculate_charge(charge)). to eq(Money.new(0)) end @@ -211,7 +211,7 @@ enterprise_plan expect(pool.find_price_plan).to eq(ManageIQ::Consumption::ShowbackPricePlan.first) pool.calculate_charge(nil) - expect(pool.errors.details[:showback_charge]). to include(:error => "not found") + expect(pool.errors.details[:showback_data_view]). to include(:error => "not found") expect(pool.calculate_charge(nil)). to eq(0) end @@ -236,38 +236,38 @@ st.save pool.add_event(event2) event2.reload - pool.showback_charges.reload - charge = pool.showback_charges.find_by(:showback_event => event2) + pool.showback_data_views.reload + charge = pool.showback_data_views.find_by(:showback_data_rollup => event2) charge.cost = Money.new(0) charge.save expect { pool.calculate_charge(charge) }.to change(charge, :cost) - .from(Money.new(0)).to(Money.new((event2.reload.get_measure_value('CPU', 'average') * 12) + 67)) + .from(Money.new(0)).to(Money.new((event2.reload.get_group_value('CPU', 'average') * 12) + 67)) end it '#Add an event' do - event = FactoryGirl.create(:showback_event) - expect { pool.add_charge(event, 5) }.to change(pool.showback_charges, :count).by(1) + event = FactoryGirl.create(:showback_data_rollup) + expect { pool.add_charge(event, 5) }.to change(pool.showback_data_views, :count).by(1) end it 'update a charge in the pool with add_charge' do - charge = FactoryGirl.create(:showback_charge, :showback_pool => pool) + charge = FactoryGirl.create(:showback_data_view, :showback_envelope => pool) expect { pool.add_charge(charge, 5) }.to change(charge, :cost).to(Money.new(5)) end it 'update a charge in the pool with update_charge' do - charge = FactoryGirl.create(:showback_charge, :showback_pool => pool) + charge = FactoryGirl.create(:showback_data_view, :showback_envelope => pool) expect { pool.update_charge(charge, 5) }.to change(charge, :cost).to(Money.new(5)) end it 'update a charge in the pool gets nil if the charge is not there' do - charge = FactoryGirl.create(:showback_charge) # not in the pool + charge = FactoryGirl.create(:showback_data_view) # not in the pool expect(pool.update_charge(charge, 5)).to be_nil end it '#clear_charge' do pool.add_event(event) - pool.showback_charges.reload - charge = pool.showback_charges.find_by(:showback_event => event) + pool.showback_data_views.reload + charge = pool.showback_data_views.find_by(:showback_data_rollup => event) charge.cost = Money.new(5) expect { pool.clear_charge(charge) }.to change(charge, :cost).from(Money.new(5)).to(Money.new(0)) end @@ -276,7 +276,7 @@ pool.add_charge(event, Money.new(57)) pool.add_charge(event2, Money.new(123)) pool.clean_all_charges - pool.showback_charges.each do |x| + pool.showback_data_views.each do |x| expect(x.cost).to eq(Money.new(0)) end end @@ -297,17 +297,17 @@ tier.fixed_rate = Money.new(67) tier.variable_rate = Money.new(12) tier.save - ev = FactoryGirl.create(:showback_event, :with_vm_data, :full_month, :resource => vm) - ev2 = FactoryGirl.create(:showback_event, :with_vm_data, :full_month, :resource => vm) + ev = FactoryGirl.create(:showback_data_rollup, :with_vm_data, :full_month, :resource => vm) + ev2 = FactoryGirl.create(:showback_data_rollup, :with_vm_data, :full_month, :resource => vm) pool.add_event(ev) pool.add_event(ev2) - pool.showback_charges.reload - pool.showback_charges.each do |x| + pool.showback_data_views.reload + pool.showback_data_views.each do |x| expect(x.cost).to eq(Money.new(0)) end - pool.showback_charges.reload + pool.showback_data_views.reload pool.calculate_all_charges - pool.showback_charges.each do |x| + pool.showback_data_views.each do |x| expect(x.cost).not_to eq(Money.new(0)) end end @@ -318,21 +318,21 @@ pool.save # event.save event - expect { pool.showback_events << event }.to change(pool.showback_events, :count).by(1) - expect(pool.showback_events.last).to eq(event) + expect { pool.showback_data_rollups << event }.to change(pool.showback_data_rollups, :count).by(1) + expect(pool.showback_data_rollups.last).to eq(event) end it 'events can be associated to costs' do pool.save # event.save event - expect { pool.showback_events << event }.to change(pool.showback_charges, :count).by(1) - charge = pool.showback_charges.last - expect(charge.showback_event).to eq(event) + expect { pool.showback_data_rollups << event }.to change(pool.showback_data_views, :count).by(1) + charge = pool.showback_data_views.last + expect(charge.showback_data_rollup).to eq(event) expect { charge.cost = Money.new(3) }.to change(charge, :cost).from(0).to(Money.new(3)) end it 'monetized cost' do - expect(ManageIQ::Consumption::ShowbackCharge).to monetize(:cost) + expect(ManageIQ::Consumption::ShowbackDataView).to monetize(:cost) end pending 'charges can be updated for an event' diff --git a/spec/models/showback_input_measure_spec.rb b/spec/models/showback_input_measure_spec.rb new file mode 100644 index 0000000..3d2a550 --- /dev/null +++ b/spec/models/showback_input_measure_spec.rb @@ -0,0 +1,81 @@ +require 'spec_helper' +require 'money-rails/test_helpers' + +describe ManageIQ::Consumption::ShowbackInputMeasure do + before(:each) do + ManageIQ::Consumption::ShowbackInputMeasure.delete_all + end + + context "validations" do + let(:input_measure) { FactoryGirl.build(:showback_input_measure) } + let(:data_rollup) { FactoryGirl.build(:showback_data_rollup) } + + it "has a valid factory" do + expect(input_measure).to be_valid + end + it "should ensure presence of entity" do + input_measure.entity = nil + expect(input_measure).not_to be_valid + end + + it "should ensure presence of entity included in VALID_entity fail" do + input_measure.entity = "region" + expect(input_measure).to be_valid + end + + it "should ensure presence of description" do + input_measure.description = nil + input_measure.valid? + expect(input_measure.errors[:description]).to include "can't be blank" + end + + it "should ensure presence of usage type" do + input_measure.group = nil + input_measure.valid? + expect(input_measure.errors.messages[:group]).to include "can't be blank" + end + + it "should invalidate incorrect usage type" do + input_measure.group = "AA" + expect(input_measure).to be_valid + end + + it "should validate correct usage type" do + input_measure.group = "CPU" + expect(input_measure).to be_valid + end + + it "should ensure presence of fields included in VALID_TYPES" do + input_measure.fields = %w(average number) + expect(input_measure).to be_valid + end + + it 'should return entity::group' do + expect(input_measure.name).to eq("Vm::CPU") + end + + it 'should be a function to calculate this usage' do + described_class.seed + described_class.all.each do |usage| + usage.fields.each do |dim| + expect(data_rollup).to respond_to("#{usage.group}_#{dim}") + end + end + end + end + + context ".seed" do + let(:expected_showback_input_measure_count) { 28 } + + it "empty table" do + described_class.seed + expect(described_class.count).to eq(expected_showback_input_measure_count) + end + + it "run twice" do + described_class.seed + described_class.seed + expect(described_class.count).to eq(expected_showback_input_measure_count) + end + end +end diff --git a/spec/models/showback_price_plan_spec.rb b/spec/models/showback_price_plan_spec.rb index b9246f3..a26d969 100644 --- a/spec/models/showback_price_plan_spec.rb +++ b/spec/models/showback_price_plan_spec.rb @@ -2,9 +2,9 @@ require 'money-rails/test_helpers' RSpec.describe ManageIQ::Consumption::ShowbackPricePlan, :type => :model do - # We need to ShowbackUsageType list to know what measures we should be looking for + # We need to ShowbackInputgroup list to know what groups we should be looking for before(:each) do - ManageIQ::Consumption::ShowbackUsageType.seed + ManageIQ::Consumption::ShowbackInputMeasure.seed end context 'basic tests' do @@ -47,7 +47,7 @@ context 'rating with no context' do let(:resource) { FactoryGirl.create(:vm) } - let(:event) { FactoryGirl.build(:showback_event, :with_vm_data, :full_month, :resource => resource) } + let(:event) { FactoryGirl.build(:showback_data_rollup, :with_vm_data, :full_month, :resource => resource) } let(:fixed_rate) { Money.new(11) } let(:variable_rate) { Money.new(7) } let(:fixed_rate2) { Money.new(5) } @@ -85,14 +85,14 @@ it 'calculates costs when rate is not found' do event.save event.reload - # Make rate category not found - rate.category = 'not-found' + # Make rate entity not found + rate.entity = 'not-found' rate.save expect(plan.calculate_total_cost(event)).to(eq(Money.new(0))) end it 'calculates list of costs when rate is not found and default event data' do - rate.category = 'not-found' + rate.entity = 'not-found' rate.save resource_type = event.resource.type data = event.data @@ -100,7 +100,7 @@ end it 'calculates costs when rate is not found and event data' do - rate.category = 'not-found' + rate.entity = 'not-found' rate.save resource_type = event.resource.type data = event.data @@ -145,7 +145,7 @@ context 'rating with context' do let(:resource) { FactoryGirl.create(:vm) } - let(:event) { FactoryGirl.build(:showback_event, :with_vm_data, :full_month, :with_tags_in_context, :resource => resource) } + let(:event) { FactoryGirl.build(:showback_data_rollup, :with_vm_data, :full_month, :with_tags_in_context, :resource => resource) } let(:fixed_rate) { Money.new(11) } let(:variable_rate) { Money.new(7) } let(:plan) { FactoryGirl.create(:showback_price_plan) } @@ -174,8 +174,8 @@ it 'returns list of costs when no rate is found' do event.save event.reload - # Make rate category not found - rate.category = 'not-found' + # Make rate entity not found + rate.entity = 'not-found' rate.save expect(plan.calculate_list_of_costs(event)).to be_empty end @@ -183,8 +183,8 @@ it 'calculates costs when rate is not found' do event.save event.reload - # Make rate category not found - rate.category = 'not-found' + # Make rate entity not found + rate.entity = 'not-found' rate.save expect(plan.calculate_total_cost(event)).to eq(Money.new(0)) end diff --git a/spec/models/showback_rate_spec.rb b/spec/models/showback_rate_spec.rb index 31d1e3c..ac28bdd 100644 --- a/spec/models/showback_rate_spec.rb +++ b/spec/models/showback_rate_spec.rb @@ -3,7 +3,7 @@ module ManageIQ::Consumption describe ShowbackRate do before(:each) do - ShowbackUsageType.seed + ShowbackInputMeasure.seed end describe 'model validations' do let(:showback_rate) { FactoryGirl.build(:showback_rate) } @@ -17,11 +17,11 @@ module ManageIQ::Consumption expect(sr.showback_tiers.count).to eq(1) end - it 'returns name as category + dimension' do - category = showback_rate.category - dimension = showback_rate.dimension - measure = showback_rate.measure - expect(showback_rate.name).to eq("#{category}:#{measure}:#{dimension}") + it 'returns name as entity + field' do + entity = showback_rate.entity + field = showback_rate.field + group = showback_rate.group + expect(showback_rate.name).to eq("#{entity}:#{group}:#{field}") end it 'is not valid with a nil calculation' do @@ -45,16 +45,16 @@ module ManageIQ::Consumption expect(showback_rate.errors.details[:calculation]). to include(:error => :inclusion, :value => 'ERROR') end - it 'is not valid with a nil category' do - showback_rate.category = nil + it 'is not valid with a nil entity' do + showback_rate.entity = nil showback_rate.valid? - expect(showback_rate.errors.details[:category]).to include(:error=>:blank) + expect(showback_rate.errors.details[:entity]).to include(:error=>:blank) end - it 'is not valid with a nil dimension' do - showback_rate.dimension = nil + it 'is not valid with a nil field' do + showback_rate.field = nil showback_rate.valid? - expect(showback_rate.errors.details[:dimension]).to include(:error=>:blank) + expect(showback_rate.errors.details[:field]).to include(:error=>:blank) end it 'is valid with a nil concept' do @@ -63,16 +63,16 @@ module ManageIQ::Consumption expect(showback_rate).to be_valid end - it '#measure is valid with a non empty string' do - showback_rate.measure = 'Hz' + it '#group is valid with a non empty string' do + showback_rate.group = 'Hz' showback_rate.valid? expect(showback_rate).to be_valid end - it '#measure is not valid when nil' do - showback_rate.measure = nil + it '#group is not valid when nil' do + showback_rate.group = nil showback_rate.valid? - expect(showback_rate.errors.details[:measure]).to include(:error => :blank) + expect(showback_rate.errors.details[:group]).to include(:error => :blank) end it 'is valid with a JSON screener' do @@ -106,36 +106,36 @@ module ManageIQ::Consumption tier.save tier end - let(:showback_event_fm) { FactoryGirl.create(:showback_event, :full_month, :with_vm_data) } + let(:showback_data_rollup_fm) { FactoryGirl.create(:showback_data_rollup, :full_month, :with_vm_data) } context 'empty #context, default rate per_time and per_unit' do it 'should charge an event by occurrence when event exists' do showback_tier - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'occurrence' - expect(showback_rate.rate(showback_event_fm)).to eq(fixed_rate + variable_rate) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(fixed_rate + variable_rate) end it 'should charge an event by occurrence only the fixed rate when value is nil' do showback_tier - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'occurrence' - showback_event_fm.data = {} # There is no data for this rate in the event - expect(showback_rate.rate(showback_event_fm)).to eq(fixed_rate) + showback_data_rollup_fm.data = {} # There is no data for this rate in the event + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(fixed_rate) end it 'should charge an event by duration' do showback_tier - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'duration' - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 2)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 2)) end it 'should charge an event by quantity' do showback_tier - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'quantity' - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 2)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 2)) end end @@ -151,29 +151,29 @@ module ManageIQ::Consumption tier.save tier end - let(:showback_event_fm) { FactoryGirl.create(:showback_event, :full_month, :with_vm_data) } - let(:showback_event_hm) { FactoryGirl.create(:showback_event, :first_half_month, :with_vm_data) } + let(:showback_data_rollup_fm) { FactoryGirl.create(:showback_data_rollup, :full_month, :with_vm_data) } + let(:showback_data_rollup_hm) { FactoryGirl.create(:showback_data_rollup, :first_half_month, :with_vm_data) } it 'nil step should behave like no step' do - showback_event_fm.reload + showback_data_rollup_fm.reload showback_tier.step_unit = nil showback_tier.step_value = nil showback_tier.step_time_value = nil showback_tier.step_time_unit = nil showback_tier.save showback_rate.calculation = 'duration' - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 2048)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 2048)) end it 'basic unit step should behave like no step' do - showback_event_fm.reload + showback_data_rollup_fm.reload showback_tier.step_unit = 'b' showback_tier.step_value = 1 showback_tier.step_time_value = nil showback_tier.step_time_unit = nil showback_tier.save showback_rate.calculation = 'duration' - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 2048)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 2048)) end it 'when input is 0 it works' do @@ -182,33 +182,33 @@ module ManageIQ::Consumption showback_tier.step_time_value = nil showback_tier.step_time_unit = nil showback_rate.calculation = 'duration' - showback_event_fm.data["MEM"]["max_mem"][0] = 0 - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11)) + showback_data_rollup_fm.data["MEM"]["max_mem"][0] = 0 + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11)) end it 'should work if step unit is a subunit of the tier' do - showback_event_fm.reload + showback_data_rollup_fm.reload showback_tier.step_unit = 'Gib' showback_tier.step_value = 1 showback_tier.step_time_value = nil showback_tier.step_time_unit = nil showback_rate.calculation = 'duration' showback_tier.save - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 2048)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 2048)) showback_tier.step_value = 4 showback_tier.step_unit = 'Gib' showback_tier.save - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 4096)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 4096)) # Modify the input data so the data is not a multiple - showback_event_fm.data["MEM"]["max_mem"][0] = 501 - showback_event_fm.data["MEM"]["max_mem"][1] = 'MiB' + showback_data_rollup_fm.data["MEM"]["max_mem"][0] = 501 + showback_data_rollup_fm.data["MEM"]["max_mem"][1] = 'MiB' showback_tier.step_unit = 'MiB' showback_tier.step_value = 384 showback_tier.save - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 384 * 2)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 384 * 2)) end pending 'step time moves half_month to full_month' do @@ -217,7 +217,7 @@ module ManageIQ::Consumption showback_tier.step_time_value = 1 showback_tier.step_time_unit = 'month' showback_rate.calculation = 'duration' - expect(showback_rate.rate(showback_event_hm)).to eq(showback_rate.rate(showback_event_fm)) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(showback_rate.rate(showback_data_rollup_fm)) end pending 'step is not a subunit of the tier' do @@ -227,7 +227,7 @@ module ManageIQ::Consumption showback_tier.step_time_value = nil showback_tier.step_time_unit = nil showback_rate.calculation = 'duration' - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + 7 * 2)) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + 7 * 2)) end pending 'step is higher than the tier' @@ -235,50 +235,50 @@ module ManageIQ::Consumption context 'empty #context, modified per_time' do it 'should charge an event by occurrence' do - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'occurrence' showback_tier.fixed_rate_per_time = 'daily' showback_tier.variable_rate_per_time = 'daily' showback_tier.save days_in_month = Time.days_in_month(Time.current.month) - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(days_in_month * (11 + 7))) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(days_in_month * (11 + 7))) end it 'should charge an event by duration' do showback_tier - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'duration' showback_tier.fixed_rate_per_time = 'daily' showback_tier.variable_rate_per_time = 'daily' showback_tier.save days_in_month = Time.days_in_month(Time.current.month) - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(days_in_month * (11 + 7 * 2))) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(days_in_month * (11 + 7 * 2))) end it 'should charge an event by quantity' do - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'quantity' showback_tier.fixed_rate_per_time = 'daily' showback_tier.variable_rate_per_time = 'daily' showback_tier.save days_in_month = Time.days_in_month(Time.current.month) # Fixed is 11 per day, variable is 7 per CPU, event has average of 2 CPU - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new((days_in_month * 11) + (7 * 2))) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new((days_in_month * 11) + (7 * 2))) end end context 'empty context, modified per unit' do it 'should charge an event by duration' do - showback_event_fm.reload + showback_data_rollup_fm.reload showback_rate.calculation = 'duration' - showback_rate.dimension = 'max_mem' - showback_rate.measure = 'MEM' + showback_rate.field = 'max_mem' + showback_rate.group = 'MEM' showback_tier.variable_rate_per_unit = 'b' showback_tier.save - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + (2048 * 1024 * 1024 * 7))) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + (2048 * 1024 * 1024 * 7))) showback_tier.variable_rate_per_unit = 'Kib' showback_tier.save - expect(showback_rate.rate(showback_event_fm)).to eq(Money.new(11 + (2048 * 1024 * 7))) + expect(showback_rate.rate(showback_data_rollup_fm)).to eq(Money.new(11 + (2048 * 1024 * 7))) end pending 'should charge an event by quantity' @@ -301,7 +301,7 @@ module ManageIQ::Consumption let(:fixed_rate) { Money.new(11) } let(:variable_rate) { Money.new(7) } let(:showback_rate) { FactoryGirl.create(:showback_rate, :CPU_number, :calculation => 'quantity') } - let(:showback_event_hm) { FactoryGirl.create(:showback_event, :first_half_month, :with_vm_data) } + let(:showback_data_rollup_hm) { FactoryGirl.create(:showback_data_rollup, :first_half_month, :with_vm_data) } let(:showback_tier) do tier = showback_rate.showback_tiers.first tier.fixed_rate = fixed_rate @@ -326,44 +326,44 @@ module ManageIQ::Consumption end context 'use only a single tier' do it 'should charge an event by quantity with 1 tier with tiers_use_full_value' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_tier showback_tier_second - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(11 + 7 * 2)) - showback_event_hm.data['CPU']['number'][0] = 4.0 - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(15 + 10 * 4)) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(11 + 7 * 2)) + showback_data_rollup_hm.data['CPU']['number'][0] = 4.0 + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(15 + 10 * 4)) end it 'should charge an event by quantity with 1 tier with not tiers_use_full_value' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_tier showback_tier_second showback_rate.tiers_use_full_value = false - showback_rate.step_variable = 'cores' - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(11 + 7 * (2 - 0))) - showback_event_hm.data['CPU']['number'][0] = 4.0 - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(15 + (10 * (4 - 3.0)))) + showback_rate.tier_input_variable = 'cores' + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(11 + 7 * (2 - 0))) + showback_data_rollup_hm.data['CPU']['number'][0] = 4.0 + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(15 + (10 * (4 - 3.0)))) end end context 'with all tiers' do it 'should charge an event by quantity with 2 tiers with tiers_use_full_value' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_tier showback_tier_second showback_rate.uses_single_tier = false - showback_event_hm.data['CPU']['number'][0] = 4.0 - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(11 + 7 * 4) + Money.new(15 + 10 * 4)) + showback_data_rollup_hm.data['CPU']['number'][0] = 4.0 + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(11 + 7 * 4) + Money.new(15 + 10 * 4)) end it 'should charge an event by quantity with 2 tiers with not tiers_use_full_value' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_tier showback_tier_second showback_rate.uses_single_tier = false showback_rate.tiers_use_full_value = false - showback_rate.step_variable = 'cores' - showback_event_hm.data['CPU']['number'][0] = 4.0 - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(11 + 7 * (4 - 0)) + Money.new(15 + 10 * (4 - 3.0))) + showback_rate.tier_input_variable = 'cores' + showback_data_rollup_hm.data['CPU']['number'][0] = 4.0 + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(11 + 7 * (4 - 0)) + Money.new(15 + 10 * (4 - 3.0))) end end end @@ -371,8 +371,8 @@ module ManageIQ::Consumption let(:fixed_rate) { Money.new(11) } let(:variable_rate) { Money.new(7) } let(:showback_rate) { FactoryGirl.create(:showback_rate, :CPU_number) } - let(:showback_event_hm) { FactoryGirl.create(:showback_event, :first_half_month, :with_vm_data) } - let(:proration) { showback_event_hm.time_span.to_f / showback_event_hm.month_duration } + let(:showback_data_rollup_hm) { FactoryGirl.create(:showback_data_rollup, :first_half_month, :with_vm_data) } + let(:proration) { showback_data_rollup_hm.time_span.to_f / showback_data_rollup_hm.month_duration } let(:showback_tier) do tier = showback_rate.showback_tiers.first tier.fixed_rate = fixed_rate @@ -386,55 +386,55 @@ module ManageIQ::Consumption it 'should charge an event by occurrence' do showback_tier showback_rate.calculation = 'occurrence' - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(11) + Money.new(7)) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(11) + Money.new(7)) end it 'should charge an event by duration' do showback_tier - showback_event_hm.reload + showback_data_rollup_hm.reload showback_rate.calculation = 'duration' - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(11 + 7 * 2) * proration) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(11 + 7 * 2) * proration) end it 'should charge an event by quantity' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_tier showback_rate.calculation = 'quantity' # Fixed is 11 per day, variable is 7 per CPU, event has 2 CPU - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(11 + 7 * 2)) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(11 + 7 * 2)) end end context 'empty #context, modified per_time' do it 'should charge an event by occurrence' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_rate.calculation = 'occurrence' showback_tier.fixed_rate_per_time = 'daily' showback_tier.variable_rate_per_time = 'daily' showback_tier.save days_in_month = Time.days_in_month(Time.current.month) - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(days_in_month * (11 + 7))) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(days_in_month * (11 + 7))) end it 'should charge an event by duration' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_rate.calculation = 'duration' showback_tier.fixed_rate_per_time = 'daily' showback_tier.variable_rate_per_time = 'daily' showback_tier.save days_in_month = Time.days_in_month(Time.current.month) - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new(days_in_month * proration * (11 + 7 * 2))) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new(days_in_month * proration * (11 + 7 * 2))) end it 'should charge an event by quantity' do - showback_event_hm.reload + showback_data_rollup_hm.reload showback_rate.calculation = 'quantity' showback_tier.fixed_rate_per_time = 'daily' showback_tier.variable_rate_per_time = 'daily' showback_tier.save days_in_month = Time.days_in_month(Time.current.month) # Fixed is 11 per day, variable is 7 per CPU, event has 2 CPU - expect(showback_rate.rate(showback_event_hm)).to eq(Money.new((days_in_month * 11) + (7 * 2))) + expect(showback_rate.rate(showback_data_rollup_hm)).to eq(Money.new((days_in_month * 11) + (7 * 2))) end end diff --git a/spec/models/showback_tier_spec.rb b/spec/models/showback_tier_spec.rb index b8c23bb..095f90e 100644 --- a/spec/models/showback_tier_spec.rb +++ b/spec/models/showback_tier_spec.rb @@ -11,7 +11,7 @@ end it 'returns a name' do - expect(showback_tier.name).to eq("#{showback_rate.category}:#{showback_rate.measure}:#{showback_rate.dimension}:Tier:#{showback_tier.tier_start_value}-#{showback_tier.tier_end_value}") + expect(showback_tier.name).to eq("#{showback_rate.entity}:#{showback_rate.group}:#{showback_rate.field}:Tier:#{showback_tier.tier_start_value}-#{showback_tier.tier_end_value}") end it 'is not valid with a nil fixed_rate' do diff --git a/spec/models/showback_usage_type_spec.rb b/spec/models/showback_usage_type_spec.rb deleted file mode 100644 index 5b6c8f2..0000000 --- a/spec/models/showback_usage_type_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'spec_helper' -require 'money-rails/test_helpers' - -describe ManageIQ::Consumption::ShowbackUsageType do - before(:each) do - ManageIQ::Consumption::ShowbackUsageType.delete_all - end - - context "validations" do - let(:showback_usage) { FactoryGirl.build(:showback_usage_type) } - let(:event) { FactoryGirl.build(:showback_event) } - - it "has a valid factory" do - expect(showback_usage).to be_valid - end - it "should ensure presence of category" do - showback_usage.category = nil - expect(showback_usage).not_to be_valid - end - - it "should ensure presence of category included in VALID_CATEGORY fail" do - showback_usage.category = "region" - expect(showback_usage).to be_valid - end - - it "should ensure presence of description" do - showback_usage.description = nil - showback_usage.valid? - expect(showback_usage.errors[:description]).to include "can't be blank" - end - - it "should ensure presence of usage type" do - showback_usage.measure = nil - showback_usage.valid? - expect(showback_usage.errors.messages[:measure]).to include "can't be blank" - end - - it "should invalidate incorrect usage type" do - showback_usage.measure = "AA" - expect(showback_usage).to be_valid - end - - it "should validate correct usage type" do - showback_usage.measure = "CPU" - expect(showback_usage).to be_valid - end - - it "should ensure presence of dimensions included in VALID_TYPES" do - showback_usage.dimensions = %w(average number) - expect(showback_usage).to be_valid - end - - it 'should return category::measure' do - expect(showback_usage.name).to eq("Vm::CPU") - end - - it 'should be a function to calculate this usage' do - described_class.seed - described_class.all.each do |usage| - usage.dimensions.each do |dim| - expect(event).to respond_to("#{usage.measure}_#{dim}") - end - end - end - end - - context ".seed" do - let(:expected_showback_usage_type_count) { 28 } - - it "empty table" do - described_class.seed - expect(described_class.count).to eq(expected_showback_usage_type_count) - end - - it "run twice" do - described_class.seed - described_class.seed - expect(described_class.count).to eq(expected_showback_usage_type_count) - end - end -end