Skip to content

Commit

Permalink
Merge pull request #866 from OpenC3/python_testing
Browse files Browse the repository at this point in the history
Python testing
  • Loading branch information
jmthomas authored Oct 17, 2023
2 parents 320dcf8 + 317e98f commit fc401ed
Show file tree
Hide file tree
Showing 138 changed files with 4,382 additions and 1,091 deletions.
13 changes: 10 additions & 3 deletions openc3-cosmos-script-runner-api/scripts/running_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,6 @@ def pre_line_instrumentation(

self.handle_potential_tab_change(filename)


line_number = line_number + self.line_offset
detail_string = None
if filename:
Expand Down Expand Up @@ -1188,6 +1187,10 @@ def output_thread(self):

openc3.script.RUNNING_SCRIPT = RunningScript

###########################################################################
# START PUBLIC API
###########################################################################


def step_mode():
RunningScript.instance.step()
Expand Down Expand Up @@ -1275,9 +1278,8 @@ def start(procedure_name):
setattr(openc3.script, "start", start)


# Require an additional ruby file
# Load an additional python file
def load_utility(procedure_name):
# Ensure require_utility works like require where you don't need the .rb extension
extension = os.path.splitext(procedure_name)[1]
if extension != ".py":
procedure_name += ".py"
Expand All @@ -1300,6 +1302,11 @@ def load_utility(procedure_name):
return not_cached


###########################################################################
# END PUBLIC API
###########################################################################


setattr(openc3.script, "load_utility", load_utility)
setattr(openc3.script, "require_utility", load_utility)

Expand Down
42 changes: 23 additions & 19 deletions openc3/lib/openc3/api/cmd_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,39 +62,39 @@ module Api
#
# Favor the first syntax where possible as it is more succinct.
def cmd(*args, **kwargs)
cmd_implementation('cmd', *args, range_check: true, hazardous_check: true, raw: false, **kwargs)
_cmd_implementation('cmd', *args, range_check: true, hazardous_check: true, raw: false, **kwargs)
end
def cmd_raw(*args, **kwargs)
cmd_implementation('cmd_raw', *args, range_check: true, hazardous_check: true, raw: true, **kwargs)
_cmd_implementation('cmd_raw', *args, range_check: true, hazardous_check: true, raw: true, **kwargs)
end

# Send a command packet to a target without performing any value range
# checks on the parameters. Useful for testing to allow sending command
# parameters outside the allowable range as defined in the configuration.
def cmd_no_range_check(*args, **kwargs)
cmd_implementation('cmd_no_range_check', *args, range_check: false, hazardous_check: true, raw: false, **kwargs)
_cmd_implementation('cmd_no_range_check', *args, range_check: false, hazardous_check: true, raw: false, **kwargs)
end
def cmd_raw_no_range_check(*args, **kwargs)
cmd_implementation('cmd_raw_no_range_check', *args, range_check: false, hazardous_check: true, raw: true, **kwargs)
_cmd_implementation('cmd_raw_no_range_check', *args, range_check: false, hazardous_check: true, raw: true, **kwargs)
end

# Send a command packet to a target without performing any hazardous checks
# both on the command itself and its parameters. Useful in scripts to
# prevent popping up warnings to the user.
def cmd_no_hazardous_check(*args, **kwargs)
cmd_implementation('cmd_no_hazardous_check', *args, range_check: true, hazardous_check: false, raw: false, **kwargs)
_cmd_implementation('cmd_no_hazardous_check', *args, range_check: true, hazardous_check: false, raw: false, **kwargs)
end
def cmd_raw_no_hazardous_check(*args, **kwargs)
cmd_implementation('cmd_raw_no_hazardous_check', *args, range_check: true, hazardous_check: false, raw: true, **kwargs)
_cmd_implementation('cmd_raw_no_hazardous_check', *args, range_check: true, hazardous_check: false, raw: true, **kwargs)
end

# Send a command packet to a target without performing any value range
# checks or hazardous checks both on the command itself and its parameters.
def cmd_no_checks(*args, **kwargs)
cmd_implementation('cmd_no_checks', *args, range_check: false, hazardous_check: false, raw: false, **kwargs)
_cmd_implementation('cmd_no_checks', *args, range_check: false, hazardous_check: false, raw: false, **kwargs)
end
def cmd_raw_no_checks(*args, **kwargs)
cmd_implementation('cmd_raw_no_checks', *args, range_check: false, hazardous_check: false, raw: true, **kwargs)
_cmd_implementation('cmd_raw_no_checks', *args, range_check: false, hazardous_check: false, raw: true, **kwargs)
end

# Build a command binary
Expand Down Expand Up @@ -285,29 +285,30 @@ def get_cmd_time(target_name = nil, command_name = nil, scope: $openc3_scope, to
target_name = target_name.upcase
command_name = command_name.upcase
time = CommandDecomTopic.get_cmd_item(target_name, command_name, 'RECEIVED_TIMESECONDS', type: :CONVERTED, scope: scope)
[target_name, command_name, time.to_i, ((time.to_f - time.to_i) * 1_000_000).to_i]
return [target_name, command_name, time.to_i, ((time.to_f - time.to_i) * 1_000_000).to_i]
else
if target_name.nil?
targets = TargetModel.names(scope: scope)
else
target_name = target_name.upcase
targets = [target_name]
end
targets.each do |target_name|
time = 0
command_name = nil
TargetModel.packets(target_name, type: :CMD, scope: scope).each do |packet|
cur_time = CommandDecomTopic.get_cmd_item(target_name, packet["packet_name"], 'RECEIVED_TIMESECONDS', type: :CONVERTED, scope: scope)
time = 0
command_name = nil
targets.each do |cur_target|
TargetModel.packets(cur_target, type: :CMD, scope: scope).each do |packet|
cur_time = CommandDecomTopic.get_cmd_item(cur_target, packet["packet_name"], 'RECEIVED_TIMESECONDS', type: :CONVERTED, scope: scope)
next unless cur_time

if cur_time > time
time = cur_time
command_name = packet["packet_name"]
target_name = cur_target
end
end
target_name = nil unless command_name
return [target_name, command_name, time.to_i, ((time.to_f - time.to_i) * 1_000_000).to_i]
end
target_name = nil unless command_name
return [target_name, command_name, time.to_i, ((time.to_f - time.to_i) * 1_000_000).to_i]
end
end

Expand All @@ -330,6 +331,9 @@ def get_cmd_cnt(target_name, command_name, scope: $openc3_scope, token: $openc3_
# @return [Numeric] Transmit count for the command
def get_cmd_cnts(target_commands, scope: $openc3_scope, token: $openc3_token)
authorize(permission: 'system', scope: scope, token: token)
unless target_commands.is_a?(Array) and target_commands[0].is_a?(Array)
raise "get_cmd_cnts takes an array of arrays containing target, packet_name, e.g. [['INST', 'COLLECT'], ['INST', 'ABORT']]"
end
counts = []
target_commands.each do |target_name, command_name|
target_name = target_name.upcase
Expand All @@ -343,7 +347,7 @@ def get_cmd_cnts(target_commands, scope: $openc3_scope, token: $openc3_token)
# PRIVATE implementation details
###########################################################################

def cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:, timeout: nil, log_message: nil,
def _cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:, timeout: nil, log_message: nil,
scope: $openc3_scope, token: $openc3_token, **kwargs)
extract_string_kwargs_to_args(args, kwargs)
unless [nil, true, false].include?(log_message)
Expand Down Expand Up @@ -399,12 +403,12 @@ def cmd_implementation(method_name, *args, range_check:, hazardous_check:, raw:,
end
end
if log_message
Logger.info(build_cmd_output_string(method_name, target_name, cmd_name, cmd_params, packet), scope: scope)
Logger.info(_build_cmd_output_string(method_name, target_name, cmd_name, cmd_params, packet), scope: scope)
end
CommandTopic.send_command(command, timeout: timeout, scope: scope)
end

def build_cmd_output_string(method_name, target_name, cmd_name, cmd_params, packet)
def _build_cmd_output_string(method_name, target_name, cmd_name, cmd_params, packet)
output_string = "#{method_name}(\""
output_string << target_name + ' ' + cmd_name
if cmd_params.nil? or cmd_params.empty?
Expand Down
6 changes: 3 additions & 3 deletions openc3/lib/openc3/api/limits_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def get_overall_limits_state(ignored_items = nil, scope: $openc3_scope, token: $
# @param args [String|Array<String>] See the description for calling style
# @return [Boolean] Whether limits are enable for the itme
def limits_enabled?(*args, scope: $openc3_scope, token: $openc3_token)
target_name, packet_name, item_name = tlm_process_args(args, 'limits_enabled?', scope: scope)
target_name, packet_name, item_name = _tlm_process_args(args, 'limits_enabled?', scope: scope)
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
return TargetModel.packet_item(target_name, packet_name, item_name, scope: scope)['limits']['enabled'] ? true : false
end
Expand All @@ -124,7 +124,7 @@ def limits_enabled?(*args, scope: $openc3_scope, token: $openc3_token)
#
# @param args [String|Array<String>] See the description for calling style
def enable_limits(*args, scope: $openc3_scope, token: $openc3_token)
target_name, packet_name, item_name = tlm_process_args(args, 'enable_limits', scope: scope)
target_name, packet_name, item_name = _tlm_process_args(args, 'enable_limits', scope: scope)
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
packet = TargetModel.packet(target_name, packet_name, scope: scope)
found_item = nil
Expand Down Expand Up @@ -157,7 +157,7 @@ def enable_limits(*args, scope: $openc3_scope, token: $openc3_token)
#
# @param args [String|Array<String>] See the description for calling style
def disable_limits(*args, scope: $openc3_scope, token: $openc3_token)
target_name, packet_name, item_name = tlm_process_args(args, 'disable_limits', scope: scope)
target_name, packet_name, item_name = _tlm_process_args(args, 'disable_limits', scope: scope)
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
packet = TargetModel.packet(target_name, packet_name, scope: scope)
found_item = nil
Expand Down
14 changes: 7 additions & 7 deletions openc3/lib/openc3/api/tlm_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ module Api
# @param type [Symbol] Telemetry type, :RAW, :CONVERTED (default), :FORMATTED, or :WITH_UNITS
# @return [Object] The telemetry value formatted as requested
def tlm(*args, type: :CONVERTED, cache_timeout: 0.1, scope: $openc3_scope, token: $openc3_token)
target_name, packet_name, item_name = tlm_process_args(args, 'tlm', cache_timeout: cache_timeout, scope: scope)
target_name, packet_name, item_name = _tlm_process_args(args, 'tlm', cache_timeout: cache_timeout, scope: scope)
authorize(permission: 'tlm', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
CvtModel.get_item(target_name, packet_name, item_name, type: type.intern, cache_timeout: cache_timeout, scope: scope)
end
Expand Down Expand Up @@ -105,7 +105,7 @@ def tlm_variable(*args, cache_timeout: 0.1, scope: $openc3_scope, token: $openc3
# @param args [String|Array<String>] See the description for calling style
# @param type [Symbol] Telemetry type, :RAW, :CONVERTED (default), :FORMATTED, or :WITH_UNITS
def set_tlm(*args, type: :CONVERTED, scope: $openc3_scope, token: $openc3_token)
target_name, packet_name, item_name, value = set_tlm_process_args(args, __method__, scope: scope)
target_name, packet_name, item_name, value = _set_tlm_process_args(args, __method__, scope: scope)
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
CvtModel.set_item(target_name, packet_name, item_name, value, type: type.intern, scope: scope)
end
Expand Down Expand Up @@ -166,7 +166,7 @@ def inject_tlm(target_name, packet_name, item_hash = nil, type: :CONVERTED, scop
# description).
# @param type [Symbol] Telemetry type, :ALL (default), :RAW, :CONVERTED, :FORMATTED, :WITH_UNITS
def override_tlm(*args, type: :ALL, scope: $openc3_scope, token: $openc3_token)
target_name, packet_name, item_name, value = set_tlm_process_args(args, __method__, scope: scope)
target_name, packet_name, item_name, value = _set_tlm_process_args(args, __method__, scope: scope)
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
CvtModel.override(target_name, packet_name, item_name, value, type: type.intern, scope: scope)
end
Expand All @@ -191,7 +191,7 @@ def get_overrides(scope: $openc3_scope, token: $openc3_token)
# @param type [Symbol] Telemetry type, :ALL (default), :RAW, :CONVERTED, :FORMATTED, :WITH_UNITS
# Also takes :ALL which means to normalize all telemetry types
def normalize_tlm(*args, type: :ALL, scope: $openc3_scope, token: $openc3_token)
target_name, packet_name, item_name = tlm_process_args(args, __method__, scope: scope)
target_name, packet_name, item_name = _tlm_process_args(args, __method__, scope: scope)
authorize(permission: 'tlm_set', target_name: target_name, packet_name: packet_name, scope: scope, token: token)
CvtModel.normalize(target_name, packet_name, item_name, type: type.intern, scope: scope)
end
Expand Down Expand Up @@ -386,7 +386,7 @@ def get_tlm_cnt(target_name, packet_name, scope: $openc3_scope, token: $openc3_t
# Get the transmit counts for telemetry packets
#
# @param target_packets [Array<Array<String, String>>] Array of arrays containing target_name, packet_name
# @return [Numeric] Transmit count for the command
# @return [Array<Numeric>] Receive count for the telemetry packets
def get_tlm_cnts(target_packets, scope: $openc3_scope, token: $openc3_token)
authorize(permission: 'system', scope: scope, token: token)
counts = []
Expand Down Expand Up @@ -427,7 +427,7 @@ def _validate_tlm_type(type)
return nil
end

def tlm_process_args(args, method_name, cache_timeout: 0.1, scope: $openc3_scope, token: $openc3_token)
def _tlm_process_args(args, method_name, cache_timeout: 0.1, scope: $openc3_scope, token: $openc3_token)
case args.length
when 1
target_name, packet_name, item_name = extract_fields_from_tlm_text(args[0])
Expand All @@ -453,7 +453,7 @@ def tlm_process_args(args, method_name, cache_timeout: 0.1, scope: $openc3_scope
return [target_name, packet_name, item_name]
end

def set_tlm_process_args(args, method_name, scope: $openc3_scope, token: $openc3_token)
def _set_tlm_process_args(args, method_name, scope: $openc3_scope, token: $openc3_token)
case args.length
when 1
target_name, packet_name, item_name, value = extract_fields_from_set_tlm_text(args[0])
Expand Down
3 changes: 2 additions & 1 deletion openc3/lib/openc3/models/cvt_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,11 @@ def self.normalize(target_name, packet_name, item_name, type: :ALL, scope: $open
end

tgt_pkt_key = "#{scope}__tlm__#{target_name}__#{packet_name}"
@@override_cache[tgt_pkt_key] = [Time.now, hash]
if hash.empty?
@@override_cache.delete(tgt_pkt_key)
Store.hdel("#{scope}__override__#{target_name}", packet_name)
else
@@override_cache[tgt_pkt_key] = [Time.now, hash]
Store.hset("#{scope}__override__#{target_name}", packet_name, JSON.generate(hash.as_json(:allow_nan => true)))
end
end
Expand Down
8 changes: 4 additions & 4 deletions openc3/lib/openc3/models/interface_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def unmap_target(target_name, cmd_only: false, tlm_only: false)
# Respawn the microservice
type = self.class._get_type
microservice_name = "#{@scope}__#{type}__#{@name}"
microservice = MicroserviceModel.get_model(name: microservice_name, scope: scope)
microservice = MicroserviceModel.get_model(name: microservice_name, scope: @scope)
microservice.target_names.delete(target_name) unless @target_names.include?(target_name)
microservice.update
end
Expand All @@ -438,11 +438,11 @@ def map_target(target_name, cmd_only: false, tlm_only: false, unmap_old: true)

if unmap_old
# Remove from old interface
all_interfaces = InterfaceModel.all(scope: scope)
all_interfaces = InterfaceModel.all(scope: @scope)
old_interface = nil
all_interfaces.each do |old_interface_name, old_interface_details|
if old_interface_details['target_names'].include?(target_name)
old_interface = InterfaceModel.from_json(old_interface_details, scope: scope)
old_interface = InterfaceModel.from_json(old_interface_details, scope: @scope)
old_interface.unmap_target(target_name, cmd_only: cmd_only, tlm_only: tlm_only) if old_interface
end
end
Expand All @@ -457,7 +457,7 @@ def map_target(target_name, cmd_only: false, tlm_only: false, unmap_old: true)
# Respawn the microservice
type = self.class._get_type
microservice_name = "#{@scope}__#{type}__#{@name}"
microservice = MicroserviceModel.get_model(name: microservice_name, scope: scope)
microservice = MicroserviceModel.get_model(name: microservice_name, scope: @scope)
microservice.target_names << target_name unless microservice.target_names.include?(target_name)
microservice.update
end
Expand Down
Loading

0 comments on commit fc401ed

Please sign in to comment.