# encoding: ascii-8bit # Copyright 2014 Ball Aerospace & Technologies Corp. # All Rights Reserved. # # This program is free software; you can modify and/or redistribute it # under the terms of the GNU General Public License # as published by the Free Software Foundation; version 3 with # attribution addendums as found in the LICENSE.txt require 'spec_helper' require 'cosmos' require 'cosmos/tools/cmd_tlm_server/limits_groups_background_task' module Cosmos describe LimitsGroupsBackgroundTask do before(:each) do (1..4).each do |i| System.telemetry.packet("INST","HEALTH_STATUS").get_item("TEMP#{i}").limits.enabled = true end end describe "initialize" do it "initializes local variables" do b1 = LimitsGroupsBackgroundTask.new expect(b1.name).to eq "Limits Groups" expect(b1.thread).to be_nil expect(b1.status).to eq '' expect(b1.stopped).to eq false expect(b1.groups).to eq %w(FIRST SECOND) end end describe "call" do it "warns if the group is not defined" do class MyLimitsGroups1 < LimitsGroupsBackgroundTask def check_blah end end expect(Logger).to receive(:warn) do |msg| expect(msg).to match(/check_blah doesn't match a group name/) end thread = Thread.new do MyLimitsGroups1.new.call end sleep 0.1 thread.kill thread.join end it "requires a floating point delay parameter" do class MyLimitsGroups1 < LimitsGroupsBackgroundTask end expect { MyLimitsGroups1.new("HI") }.to raise_error(/invalid value for Float/) end it "delays before processing the groups" do class MyLimitsGroups2 < LimitsGroupsBackgroundTask attr_accessor :called def check_first @called = Time.now end end my = MyLimitsGroups2.new(2.1) thread = Thread.new do my.call end sleep 2.2 expect(Time.now - my.called).to be < 0.15 Cosmos.kill_thread(self, thread) end it "processes the check methods at a configurable rate" do class MyLimitsGroups3 < LimitsGroupsBackgroundTask attr_accessor :first_count, :second_count, :on_logic, :off_logic def initialize(connect_delay, task_delay) super(connect_delay, task_delay) @first_count = 0 @second_count = 0 @on_logic = false @off_logic = false @on = Proc.new { @on_logic = true } @off = Proc.new { @off_logic = true } end def check_first @first_count += 1 process_group(2, @on, @off) do @first_count <= 4 ? true : false end end def check_second @second_count += 1 process_group { false } # Never enable end end my = MyLimitsGroups3.new(0, 1) # Run at 1Hz thread = Thread.new do my.call end sleep 0.1 p = System.telemetry.packet("INST","HEALTH_STATUS") # First group is enabled expect(p.get_item("TEMP1").limits.enabled).to be true expect(p.get_item("TEMP3").limits.enabled).to be true # Second group is disabled expect(p.get_item("TEMP2").limits.enabled).to be false expect(p.get_item("TEMP4").limits.enabled).to be false expect(my.on_logic).to be false expect(my.off_logic).to be false # Things not in a group are enabled expect(p.get_item("GROUND1STATUS").limits.enabled).to be true expect(p.get_item("GROUND2STATUS").limits.enabled).to be true sleep 3.1 # Allow the logic to enable expect(p.get_item("TEMP1").limits.enabled).to be true expect(p.get_item("TEMP3").limits.enabled).to be true expect(p.get_item("TEMP2").limits.enabled).to be false expect(p.get_item("TEMP4").limits.enabled).to be false expect(my.on_logic).to be true # on logic was called expect(my.off_logic).to be false # off logic not yet called sleep 2.1 # Allow the logic to disable expect(p.get_item("TEMP1").limits.enabled).to be false expect(p.get_item("TEMP3").limits.enabled).to be false expect(p.get_item("TEMP2").limits.enabled).to be false expect(p.get_item("TEMP4").limits.enabled).to be false expect(my.on_logic).to be true expect(my.off_logic).to be true # off logic called Cosmos.kill_thread(self, thread) expect(my.first_count).to be >= 5 expect(my.second_count).to be >= 5 end it "reports how long it took to process" do class MyLimitsGroups4 < LimitsGroupsBackgroundTask def check_first sleep 0.2 end end Thread.abort_on_exception = true my = MyLimitsGroups4.new thread = Thread.new do my.call end sleep 0.3 expect(my.status).to match(/Checking groups took 0.\d+/) Cosmos.kill_thread(self, thread) end end end end