cosmos 3.2.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 03a5fb5559e97c328a048705f0e90a85f3655899
4
- data.tar.gz: e3c8be6334821135b794171b088571c6dbb75062
3
+ metadata.gz: a73e644c741cdb4b6c8ee2bcc036cc82cb9156e2
4
+ data.tar.gz: 60c9ba5fd730651c722969b6a4609c72fde6cdf0
5
5
  SHA512:
6
- metadata.gz: ce712ead10d1c094ca7e811705036e66e3c9b279059f91bae5b7c5e90ae4dfc15d95be6802a467dea693b1ff957b36182f89e742b0f22e7ad723ad83f26642ea
7
- data.tar.gz: e8ce4d0a58e565a328c7d42cf821f86fdb26cc5a397ca7e3bb449c94e0f02b2aab6a93288e1342dc97d205a886f623453895ef3a6f05a024470f895efe38386b
6
+ metadata.gz: c6054c51d2b5d87f0e8932c5a70877b18b66783006082e34bfd853a9f48d5af634a5167b4c9503f6f4393f764a0d530977cd006d6151461ac17fe806ff47c2b7
7
+ data.tar.gz: 3e34446fe6492174c11f196be43c9528341713eb75b8834609da6d8594b7da371c771f1a9429a73569d3a34f3a2028b24e3a1096ccbf4423d2915421a6faf1ae
@@ -189,6 +189,7 @@ cosmos.gemspec
189
189
  data/COSMOS_64x64.bmp
190
190
  data/COSMOS_64x64.ico
191
191
  data/COSMOS_64x64.png
192
+ data/COSMOS_Architecture.png
192
193
  data/CheckBoxCheck.gif
193
194
  data/CheckBoxEmpty.gif
194
195
  data/Earthmap1024x512.gif
data/README.md CHANGED
@@ -10,6 +10,8 @@ So what can you use this for? We use it to test about everything we create and
10
10
 
11
11
  After configuring COSMOS to talk to your hardware, you immediately can use the following 15 tools:
12
12
 
13
+ ![COSMOS Architecture](data/COSMOS_Architecture.png)
14
+
13
15
  1. **Command and Telemetry Server**
14
16
  * This is the heart of the realtime functionality within the Ball Aerospace COSMOS system. It maintains realtime connections to each target in your system and is the single point for all outgoing commands and incoming telemetry packets. By default, it logs all commands and telemetry sent/received for later review and analysis. The Command and Telemetry Server also monitors limits on all telemetry packets received.
15
17
 
@@ -404,11 +404,7 @@ WinWaitActive Script Runner
404
404
  WinWaitActive Hazardous
405
405
  Sleep 500
406
406
  Send n
407
- WinWaitActive Script Runner
408
- WinWaitActive Pause or Stop
409
- Sleep 500
410
- Send {Enter} ; Pause
411
- WinWaitActive Script Runner
407
+ WinWaitActive Script Runner ; Now paused since we said no
412
408
  Sleep 500
413
409
  Click 400 90 ; Go
414
410
  WinWaitActive Hazardous
@@ -419,6 +415,10 @@ WinWaitActive Hazardous
419
415
  Sleep 500
420
416
  Send {Enter}
421
417
  WinWaitActive Script Runner
418
+ WinWaitActive Hazardous
419
+ Sleep 500
420
+ Send {Enter}
421
+ WinWaitActive Script Runner
422
422
  Sleep 2000
423
423
 
424
424
  Send ^t ; Toggle Disconnect
@@ -18,7 +18,7 @@
18
18
  "lib/cosmos/conversions/polynomial_conversion.rb" 0xF6440F21
19
19
  "lib/cosmos/conversions/received_count_conversion.rb" 0xD61BEB37
20
20
  "lib/cosmos/utilities.rb" 0xBE9CEAF4
21
- "lib/cosmos/top_level.rb" 0x4306956B
21
+ "lib/cosmos/top_level.rb" 0x1623E285
22
22
  "lib/cosmos/packet_logs/meta_packet_log_writer.rb" 0x860D1FD8
23
23
  "lib/cosmos/packet_logs/packet_log_writer.rb" 0x7C6FCFEC
24
24
  "lib/cosmos/packet_logs/packet_log_writer_pair.rb" 0xB4DCA156
@@ -53,7 +53,7 @@
53
53
  "lib/cosmos/gui/dialogs/tlm_details_dialog.rb" 0xCAD1848F
54
54
  "lib/cosmos/gui/dialogs/calendar_dialog.rb" 0x688D3D3B
55
55
  "lib/cosmos/gui/qt_tool.rb" 0x840EF801
56
- "lib/cosmos/gui/utilities/script_module_gui.rb" 0xBD605F5C
56
+ "lib/cosmos/gui/utilities/script_module_gui.rb" 0x0FFA7712
57
57
  "lib/cosmos/gui/utilities/screenshot.rb" 0x65F75371
58
58
  "lib/cosmos/gui/widgets/full_text_search_line_edit.rb" 0x7AAF694C
59
59
  "lib/cosmos/gui/widgets/realtime_button_bar.rb" 0xEB0CE858
@@ -90,7 +90,7 @@
90
90
  "lib/cosmos/gui/choosers/combobox_chooser.rb" 0xAD5383D5
91
91
  "lib/cosmos/gui/choosers/float_chooser.rb" 0x23B2FA77
92
92
  "lib/cosmos/tools/script_runner/script_runner_config.rb" 0x1E46E8AA
93
- "lib/cosmos/tools/script_runner/script_runner_frame.rb" 0x51512C6A
93
+ "lib/cosmos/tools/script_runner/script_runner_frame.rb" 0xEF604AAE
94
94
  "lib/cosmos/tools/script_runner/script_runner.rb" 0x61FFB8A2
95
95
  "lib/cosmos/tools/script_runner/script_audit.rb" 0xC4543FBA
96
96
  "lib/cosmos/tools/cmd_extractor/cmd_extractor.rb" 0xEECB31B8
@@ -99,7 +99,7 @@
99
99
  "lib/cosmos/tools/data_viewer/data_viewer.rb" 0x0F59420B
100
100
  "lib/cosmos/tools/launcher/launcher_multitool.rb" 0x1020A3D0
101
101
  "lib/cosmos/tools/launcher/launcher_tool.rb" 0x0501F2F4
102
- "lib/cosmos/tools/launcher/launcher_config.rb" 0xFF0CB90A
102
+ "lib/cosmos/tools/launcher/launcher_config.rb" 0x37573A87
103
103
  "lib/cosmos/tools/launcher/launcher.rb" 0x0FFB42EC
104
104
  "lib/cosmos/tools/replay/replay_server.rb" 0x307A7329
105
105
  "lib/cosmos/tools/replay/replay.rb" 0xB8521242
@@ -107,7 +107,7 @@
107
107
  "lib/cosmos/tools/tlm_extractor/tlm_extractor.rb" 0xC6B38C94
108
108
  "lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb" 0x7779DCEC
109
109
  "lib/cosmos/tools/tlm_extractor/text_item_chooser.rb" 0x587768C6
110
- "lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb" 0x167BC6BD
110
+ "lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb" 0xA1C38662
111
111
  "lib/cosmos/tools/cmd_tlm_server/api.rb" 0xB1819524
112
112
  "lib/cosmos/tools/cmd_tlm_server/connections.rb" 0x6657A0FB
113
113
  "lib/cosmos/tools/cmd_tlm_server/background_task.rb" 0x448A2191
@@ -123,8 +123,8 @@
123
123
  "lib/cosmos/tools/cmd_tlm_server/packet_logging.rb" 0x166BE402
124
124
  "lib/cosmos/tools/cmd_tlm_server/commanding.rb" 0xC7C76CD8
125
125
  "lib/cosmos/tools/cmd_tlm_server/interfaces.rb" 0x10BC320E
126
- "lib/cosmos/tools/cmd_tlm_server/interface_thread.rb" 0x38ED08CB
127
- "lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb" 0x138FCD7A
126
+ "lib/cosmos/tools/cmd_tlm_server/interface_thread.rb" 0x5144683A
127
+ "lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb" 0x0542EE44
128
128
  "lib/cosmos/tools/limits_monitor/limits_monitor.rb" 0xF155D8CC
129
129
  "lib/cosmos/tools/packet_viewer/packet_viewer.rb" 0x12D1B643
130
130
  "lib/cosmos/tools/table_manager/table_manager.rb" 0x4FC4AE95
@@ -134,12 +134,12 @@
134
134
  "lib/cosmos/tools/table_manager/table_config.rb" 0x177F0B14
135
135
  "lib/cosmos/tools/opengl_builder/scene_config.rb" 0x15B59793
136
136
  "lib/cosmos/tools/opengl_builder/opengl_builder.rb" 0xB161B0F9
137
- "lib/cosmos/tools/cmd_sender/cmd_sender.rb" 0x0D57B917
137
+ "lib/cosmos/tools/cmd_sender/cmd_sender.rb" 0xDA26A1FB
138
138
  "lib/cosmos/tools/cmd_sender/cmd_sender_item_delegate.rb" 0x8297CC9D
139
139
  "lib/cosmos/tools/cmd_sender/cmd_sender_text_edit.rb" 0xB192AF6E
140
140
  "lib/cosmos/tools/test_runner/test_runner_chooser.rb" 0x182F00C6
141
141
  "lib/cosmos/tools/test_runner/results_writer.rb" 0xF8CF9306
142
- "lib/cosmos/tools/test_runner/test_runner.rb" 0x4165ADBC
142
+ "lib/cosmos/tools/test_runner/test_runner.rb" 0x19B1D251
143
143
  "lib/cosmos/tools/test_runner/test.rb" 0xD2BE7F1C
144
144
  "lib/cosmos/tools/tlm_grapher/plots/xy_plot.rb" 0x98F7712F
145
145
  "lib/cosmos/tools/tlm_grapher/plots/singlexy_plot.rb" 0xA01649EC
@@ -234,7 +234,7 @@
234
234
  "lib/cosmos/tools/tlm_viewer/tlm_viewer.rb" 0x03D59CCB
235
235
  "lib/cosmos/system.rb" 0x735DFB42
236
236
  "lib/cosmos/conversions.rb" 0x43679D05
237
- "lib/cosmos/version.rb" 0x3FF1E990
237
+ "lib/cosmos/version.rb" 0x50C04271
238
238
  "lib/cosmos/core_ext.rb" 0x1951B346
239
239
  "lib/cosmos/interfaces.rb" 0x7E3EA326
240
240
  "lib/cosmos/processors.rb" 0x5241327D
@@ -246,8 +246,8 @@
246
246
  "lib/cosmos/streams/serial_stream.rb" 0x9F0BBA1D
247
247
  "lib/cosmos/streams/stream_protocol.rb" 0x5EA23890
248
248
  "lib/cosmos/streams/fixed_stream_protocol.rb" 0x5F6F224B
249
- "lib/cosmos/streams/tcpip_client_stream.rb" 0x974ED23F
250
- "lib/cosmos/streams/tcpip_socket_stream.rb" 0xD635732F
249
+ "lib/cosmos/streams/tcpip_client_stream.rb" 0xA644ADBA
250
+ "lib/cosmos/streams/tcpip_socket_stream.rb" 0xA6A94616
251
251
  "lib/cosmos/streams/preidentified_stream_protocol.rb" 0xC258238E
252
252
  "lib/cosmos/script.rb" 0x25BB611B
253
253
  "lib/cosmos/config/config_parser.rb" 0x89526FF1
@@ -277,16 +277,16 @@
277
277
  "lib/cosmos/processors/watermark_processor.rb" 0xDADF4580
278
278
  "lib/cosmos/io/stdout.rb" 0xAC9CC4B1
279
279
  "lib/cosmos/io/buffered_file.rb" 0x70A3B880
280
- "lib/cosmos/io/json_drb_object.rb" 0xD48FA273
280
+ "lib/cosmos/io/json_drb_object.rb" 0x58BE861D
281
281
  "lib/cosmos/io/cosmos_snmp.rb" 0x64541158
282
282
  "lib/cosmos/io/json_rpc.rb" 0x8EAA13F8
283
- "lib/cosmos/io/tcpip_server.rb" 0xAB7A0F48
283
+ "lib/cosmos/io/tcpip_server.rb" 0xBAA24660
284
284
  "lib/cosmos/io/posix_serial_driver.rb" 0x6DD5B8B4
285
285
  "lib/cosmos/io/udp_sockets.rb" 0xB1B138CD
286
286
  "lib/cosmos/io/serial_driver.rb" 0x9A2515F4
287
287
  "lib/cosmos/io/raw_logger_pair.rb" 0x7A0A3F00
288
288
  "lib/cosmos/io/raw_logger.rb" 0x42BC42CC
289
- "lib/cosmos/io/json_drb.rb" 0xEF9BDF14
289
+ "lib/cosmos/io/json_drb.rb" 0x00FC5705
290
290
  "lib/cosmos/io/stderr.rb" 0x401624AF
291
291
  "lib/cosmos/io/io_multiplexer.rb" 0xD183938D
292
292
  "lib/cosmos/io/win32_serial_driver.rb" 0xA7E055CA
@@ -297,9 +297,9 @@
297
297
  "lib/cosmos/interfaces/simulated_target_interface.rb" 0x15DC496F
298
298
  "lib/cosmos/interfaces/serial_interface.rb" 0xC376DDA0
299
299
  "lib/cosmos/interfaces/tcpip_client_interface.rb" 0x5F0DB50D
300
- "lib/cosmos/interfaces/udp_interface.rb" 0xA991C213
300
+ "lib/cosmos/interfaces/udp_interface.rb" 0xCE4532AD
301
301
  "lib/cosmos/interfaces/tcpip_server_interface.rb" 0xC8F6E908
302
- "lib/cosmos/script/script.rb" 0x139256FE
302
+ "lib/cosmos/script/script.rb" 0x2F64B04D
303
303
  "lib/cosmos/script/extract.rb" 0xF3243476
304
304
  "lib/cosmos/core_ext/range.rb" 0x0D55D9D1
305
305
  "lib/cosmos/core_ext/stringio.rb" 0x28B64FB4
@@ -21,8 +21,15 @@ module Cosmos
21
21
 
22
22
  @@qt_boolean = Qt::Boolean.new
23
23
 
24
- def ask_string(question, allow_blank = false, password = false)
25
- answer = ""
24
+ def ask_string(question, blank_or_default = false, password = false)
25
+ answer = ''
26
+ if blank_or_default != true && blank_or_default != false
27
+ default = blank_or_default.to_s
28
+ allow_blank = false
29
+ else
30
+ default = ''
31
+ allow_blank = blank_or_default
32
+ end
26
33
  loop do
27
34
  canceled = false
28
35
  Qt.execute_in_main_thread(true, 0.05) do
@@ -30,9 +37,9 @@ module Cosmos
30
37
  window = get_cmd_tlm_gui_window() if get_cmd_tlm_gui_window()
31
38
  # Create a special mutable QT variable that can return what button was pressed
32
39
  if password
33
- answer = Qt::InputDialog::getText(window, "Ask", question, Qt::LineEdit::Password, "", @@qt_boolean)
40
+ answer = Qt::InputDialog::getText(window, "Ask", question, Qt::LineEdit::Password, default, @@qt_boolean)
34
41
  else
35
- answer = Qt::InputDialog::getText(window, "Ask", question, Qt::LineEdit::Normal, "", @@qt_boolean)
42
+ answer = Qt::InputDialog::getText(window, "Ask", question, Qt::LineEdit::Normal, default, @@qt_boolean)
36
43
  end
37
44
  # @@qt_boolean is nil if the user presses cancel in the dialog
38
45
  # Note that it is not actually nil, just the nil? method returns true
@@ -86,42 +93,7 @@ module Cosmos
86
93
  end
87
94
 
88
95
  def prompt_for_script_abort
89
- result = nil
90
- Qt.execute_in_main_thread(true, 0.05) do
91
- window = nil
92
- window = get_cmd_tlm_gui_window() if get_cmd_tlm_gui_window()
93
- dialog = Qt::Dialog.new(window, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
94
- dialog.window_title = "Pause or Stop"
95
- dialog_layout = Qt::VBoxLayout.new
96
- dialog_layout.addWidget(Qt::Label.new('Pause or Stop Script?'))
97
- pause = Qt::PushButton.new("Pause")
98
- button_layout = Qt::HBoxLayout.new
99
- pause.connect(SIGNAL('clicked()')) do
100
- dialog.reject()
101
- end
102
- button_layout.addWidget(pause)
103
- stop = Qt::PushButton.new("Stop")
104
- stop.connect(SIGNAL('clicked()')) do
105
- dialog.accept()
106
- end
107
- button_layout.addWidget(stop)
108
- dialog_layout.addLayout(button_layout)
109
-
110
- dialog.setLayout(dialog_layout)
111
- dialog.raise
112
- if dialog.exec == Qt::Dialog::Accepted
113
- Logger.info "User pressed 'Stop'"
114
- result = 'stop'
115
- else
116
- Logger.info "User pressed 'Pause'"
117
- result = 'pause'
118
- end
119
- dialog.dispose
120
- end
121
- raise StopScript if result == 'stop'
122
- if result == 'pause' && defined? ScriptRunnerFrame
123
- ScriptRunnerFrame.instance.perform_pause
124
- end
96
+ return true # Aborted - Don't retry
125
97
  end
126
98
 
127
99
  def prompt_to_continue(string)
@@ -157,6 +129,7 @@ module Cosmos
157
129
  window = nil
158
130
  window = get_cmd_tlm_gui_window() if get_cmd_tlm_gui_window()
159
131
  msg = Qt::MessageBox.new(window)
132
+
160
133
  msg.setText(string)
161
134
  msg.setWindowTitle("Message Box")
162
135
  buttons.each {|text| msg.addButton(text, Qt::MessageBox::AcceptRole)}
@@ -91,22 +91,10 @@ module Cosmos
91
91
 
92
92
  # Close the active ports (read and/or write) and set the sockets to nil.
93
93
  def disconnect
94
- begin
95
- if @write_socket
96
- @write_socket.close unless @write_socket.closed?
97
- @write_socket = nil
98
- end
99
- rescue IOError
100
- @write_socket = nil
101
- end
102
- begin
103
- if @read_socket
104
- @read_socket.close unless @read_socket.closed?
105
- @read_socket = nil
106
- end
107
- rescue IOError
108
- @read_socket = nil
109
- end
94
+ Cosmos.close_socket(@write_socket)
95
+ @write_socket = nil
96
+ Cosmos.close_socket(@read_socket)
97
+ @read_socket = nil
110
98
  end
111
99
 
112
100
  # If the read port was given, the read_socket is read and the data returned
@@ -55,7 +55,7 @@ module Cosmos
55
55
  def stop_service
56
56
  Cosmos.kill_thread(self, @thread)
57
57
  @thread = nil
58
- @listen_socket.close if @listen_socket and !@listen_socket.closed?
58
+ Cosmos.close_socket(@listen_socket)
59
59
  @listen_socket = nil
60
60
  end
61
61
 
@@ -116,7 +116,7 @@ module Cosmos
116
116
  end
117
117
 
118
118
  if @acl and !@acl.allow_socket?(socket)
119
- socket.close
119
+ Cosmos.close_socket(socket)
120
120
  next
121
121
  end
122
122
  # Create new thread for new connection
@@ -270,7 +270,7 @@ module Cosmos
270
270
  break unless process_request(request_data, my_socket, start_time)
271
271
  else
272
272
  # Socket was closed by client
273
- my_socket.close unless my_socket.closed?
273
+ Cosmos.close_socket(my_socket)
274
274
  break
275
275
  end
276
276
  end
@@ -57,8 +57,7 @@ module Cosmos
57
57
 
58
58
  # Disconnects from the JSON server
59
59
  def disconnect
60
- socket = @socket
61
- socket.close if socket and !socket.closed?
60
+ Cosmos.close_socket(@socket)
62
61
  end
63
62
 
64
63
  # Permanently disconnects from the JSON server
@@ -92,7 +91,7 @@ module Cosmos
92
91
  rescue IO::WaitWritable
93
92
  begin
94
93
  _, sockets, _ = IO.select(nil, [@socket], nil, @connect_timeout) # wait 3-way handshake completion
95
- rescue Errno::ENOTSOCK
94
+ rescue IOError, Errno::ENOTSOCK
96
95
  disconnect()
97
96
  @socket = nil
98
97
  raise "Connect canceled"
@@ -100,13 +99,23 @@ module Cosmos
100
99
  if sockets and !sockets.empty?
101
100
  begin
102
101
  @socket.connect_nonblock(addr) # check connection failure
103
- rescue Errno::EISCONN
102
+ rescue IOError, Errno::ENOTSOCK
103
+ disconnect()
104
+ @socket = nil
105
+ raise "Connect canceled"
106
+ rescue Errno::EINPROGRESS
107
+ retry
108
+ rescue Errno::EISCONN, Errno::EALREADY
104
109
  end
105
110
  else
106
111
  disconnect()
107
112
  @socket = nil
108
113
  raise "Connect timeout"
109
114
  end
115
+ rescue IOError, Errno::ENOTSOCK
116
+ disconnect()
117
+ @socket = nil
118
+ raise "Connect canceled"
110
119
  end
111
120
  rescue => e
112
121
  raise DRb::DRbConnError, e.message
@@ -187,7 +187,7 @@ module Cosmos
187
187
  # Shutdown Listen Socket(s)
188
188
  @listen_sockets.each do |listen_socket|
189
189
  begin
190
- listen_socket.close unless listen_socket.closed?
190
+ Cosmos.close_socket(listen_socket)
191
191
  rescue IOError
192
192
  # Ok may have been closed by the thread
193
193
  end
@@ -374,9 +374,7 @@ module Cosmos
374
374
  addr = ["AF_INET", 10, "lc630", host_ip.to_s]
375
375
  if not System.instance.acl.allow_addr?(addr)
376
376
  # Reject connection
377
- if not socket.closed?
378
- socket.close()
379
- end
377
+ Cosmos.close_socket(socket)
380
378
  Logger.instance.info "Tcpip server rejected connection from #{hostname}(#{host_ip}):#{port}"
381
379
  return
382
380
  end
@@ -54,8 +54,7 @@ module Cosmos
54
54
  $cmd_tlm_server.cmd_no_hazardous_check(*args)
55
55
  Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
56
56
  else
57
- Logger.warn "Hazardous command not sent"
58
- prompt_for_script_abort
57
+ retry unless prompt_for_script_abort()
59
58
  end
60
59
  end
61
60
  end
@@ -79,8 +78,7 @@ module Cosmos
79
78
  Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
80
79
  Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params)
81
80
  else
82
- Logger.warn "Hazardous command not sent"
83
- prompt_for_script_abort
81
+ retry unless prompt_for_script_abort()
84
82
  end
85
83
  end
86
84
  end
@@ -126,8 +124,7 @@ module Cosmos
126
124
  $cmd_tlm_server.cmd_raw_no_hazardous_check(*args)
127
125
  Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
128
126
  else
129
- Logger.warn "Hazardous command not sent"
130
- prompt_for_script_abort
127
+ retry unless prompt_for_script_abort()
131
128
  end
132
129
  end
133
130
  end
@@ -151,8 +148,7 @@ module Cosmos
151
148
  Logger.warn "Command #{target_name} #{cmd_name} being sent ignoring range checks"
152
149
  Logger.info build_cmd_output_string(target_name, cmd_name, cmd_params, true)
153
150
  else
154
- Logger.warn "Hazardous command not sent"
155
- prompt_for_script_abort
151
+ retry unless prompt_for_script_abort()
156
152
  end
157
153
  end
158
154
  end
@@ -438,19 +434,27 @@ module Cosmos
438
434
  script_runner.script_set_status(message) if script_runner
439
435
  end
440
436
 
441
- def ask_string(question, allow_blank = false, password = false)
437
+ def ask_string(question, blank_or_default = false, password = false)
442
438
  answer = ''
439
+ default = ''
440
+ if blank_or_default != true && blank_or_default != false
441
+ question << " (default = #{blank_or_default})"
442
+ allow_blank = true
443
+ else
444
+ allow_blank = blank_or_default
445
+ end
443
446
  while answer.empty?
444
447
  print question + " "
445
448
  answer = gets
446
449
  answer.chomp!
447
450
  break if allow_blank
448
451
  end
452
+ answer = default if answer.empty? and !default.empty?
449
453
  return answer
450
454
  end
451
455
 
452
- def ask(question, allow_blank = false, password = false)
453
- string = ask_string(question, allow_blank, password)
456
+ def ask(question, blank_or_default = false, password = false)
457
+ string = ask_string(question, blank_or_default, password)
454
458
  value = string.convert_to_value
455
459
  return value
456
460
  end
@@ -1454,7 +1458,7 @@ module Cosmos
1454
1458
  if answer.downcase == 'y'
1455
1459
  exit
1456
1460
  else
1457
- return false
1461
+ return false # Not aborted - Retry
1458
1462
  end
1459
1463
  end
1460
1464
 
@@ -88,17 +88,23 @@ module Cosmos
88
88
  rescue IO::WaitWritable
89
89
  begin
90
90
  _, sockets, _ = IO.select(nil, [socket], nil, @connect_timeout) # wait 3-way handshake completion
91
- rescue Errno::ENOTSOCK
91
+ rescue IOError, Errno::ENOTSOCK
92
92
  raise "Connect canceled"
93
93
  end
94
94
  if sockets and !sockets.empty?
95
95
  begin
96
96
  socket.connect_nonblock(addr) # check connection failure
97
- rescue Errno::EISCONN
97
+ rescue IOError, Errno::ENOTSOCK
98
+ raise "Connect canceled"
99
+ rescue Errno::EINPROGRESS
100
+ retry
101
+ rescue Errno::EISCONN, Errno::EALREADY
98
102
  end
99
103
  else
100
104
  raise "Connect timeout"
101
105
  end
106
+ rescue IOError, Errno::ENOTSOCK
107
+ raise "Connect canceled"
102
108
  end
103
109
  end
104
110
 
@@ -66,7 +66,7 @@ module Cosmos
66
66
  # These can happen with the socket being closed while waiting on select
67
67
  data = ''
68
68
  end
69
- rescue Errno::ECONNRESET, Errno::ECONNABORTED
69
+ rescue Errno::ECONNRESET, Errno::ECONNABORTED, IOError, Errno::ENOTSOCK
70
70
  data = ''
71
71
  end
72
72
 
@@ -132,8 +132,8 @@ module Cosmos
132
132
 
133
133
  # Disconnect by closing the sockets
134
134
  def disconnect
135
- @write_socket.close if @write_socket and !@write_socket.closed?
136
- @read_socket.close if @read_socket and !@read_socket.closed?
135
+ Cosmos.close_socket(@write_socket)
136
+ Cosmos.close_socket(@read_socket)
137
137
  @connected = false
138
138
  end
139
139
 
@@ -28,6 +28,7 @@ module Cosmos
28
28
  def prompt_for_script_abort
29
29
  window = get_cmd_tlm_gui_window()
30
30
  window.statusBar.showMessage(tr("Hazardous command not sent"))
31
+ return true # Aborted - Don't retry
31
32
  end
32
33
  end #module Script
33
34
  end
@@ -120,6 +120,8 @@ module Cosmos
120
120
  when 'INTERFACE'
121
121
  usage = "INTERFACE <Name> <Filename> <Specific Parameters>"
122
122
  parser.verify_num_parameters(2, nil, usage)
123
+ interface_name = params[0].upcase
124
+ raise parser.error("Interface '#{interface_name}' defined twice") if @interfaces[interface_name]
123
125
  interface_class = Cosmos.require_class(params[1])
124
126
  if params[2]
125
127
  current_interface_or_router = interface_class.new(*params[2..-1])
@@ -129,8 +131,8 @@ module Cosmos
129
131
  current_type = :INTERFACE
130
132
  current_interface_log_added = false
131
133
  current_interface_or_router.packet_log_writer_pairs << @packet_log_writer_pairs['DEFAULT']
132
- current_interface_or_router.name = params[0].upcase
133
- @interfaces[params[0].upcase] = current_interface_or_router
134
+ current_interface_or_router.name = interface_name
135
+ @interfaces[interface_name] = current_interface_or_router
134
136
 
135
137
  when 'LOG', 'DONT_LOG', 'TARGET'
136
138
  raise parser.error("No current interface for #{keyword}") unless current_interface_or_router and current_type == :INTERFACE
@@ -197,6 +199,8 @@ module Cosmos
197
199
  when 'ROUTER'
198
200
  usage = "ROUTER <Name> <Filename> <Specific Parameters>"
199
201
  parser.verify_num_parameters(2, nil, usage)
202
+ router_name = params[0].upcase
203
+ raise parser.error("Router '#{router_name}' defined twice") if @routers[router_name]
200
204
  router_class = Cosmos.require_class(params[1])
201
205
  if params[2]
202
206
  current_interface_or_router = router_class.new(*params[2..-1])
@@ -204,8 +208,8 @@ module Cosmos
204
208
  current_interface_or_router = router_class.new
205
209
  end
206
210
  current_type = :ROUTER
207
- current_interface_or_router.name = params[0].upcase
208
- @routers[params[0].upcase] = current_interface_or_router
211
+ current_interface_or_router.name = router_name
212
+ @routers[router_name] = current_interface_or_router
209
213
 
210
214
  when 'ROUTE'
211
215
  raise parser.error("No current router for #{keyword}") unless current_interface_or_router and current_type == :ROUTER
@@ -58,6 +58,7 @@ module Cosmos
58
58
  @no_prompt = options.no_prompt
59
59
  @message_log = nil
60
60
  @output_sleeper = Sleeper.new
61
+ @first_output = 0
61
62
  @interfaces_tab = InterfacesTab.new
62
63
  @targets_tab = TargetsTab.new
63
64
  @packets_tab = PacketsTab.new(self)
@@ -192,6 +193,7 @@ module Cosmos
192
193
  def kill_tab_thread
193
194
  @tab_sleeper ||= nil
194
195
  @tab_sleeper.cancel if @tab_sleeper
196
+ Qt::CoreApplication.instance.processEvents
195
197
  Cosmos.kill_thread(self, @tab_thread)
196
198
  @tab_thread = nil
197
199
  end
@@ -296,6 +298,12 @@ module Cosmos
296
298
  @string_output.string = @string_output.string[string.length..-1]
297
299
  string.each_line {|out_line| @output.add_formatted_text(out_line); lines_to_write += out_line }
298
300
  @output.flush
301
+ if @first_output < 2
302
+ # Scroll to the bottom on the first two outputs for Linux
303
+ # Otherwise it does not stay at the bottom
304
+ @output.verticalScrollBar.value = @output.verticalScrollBar.maximum
305
+ @first_output += 1
306
+ end
299
307
  @message_log.write(lines_to_write)
300
308
  end
301
309
  end
@@ -44,6 +44,8 @@ module Cosmos
44
44
  @fatal_exception_callback = nil
45
45
  @thread = nil
46
46
  @thread_sleeper = Sleeper.new
47
+ @connection_failed_messages = []
48
+ @connection_lost_messages = []
47
49
  end
48
50
 
49
51
  # Create and start the Ruby thread that will encapsulate the interface.
@@ -183,15 +185,19 @@ module Cosmos
183
185
  if @connection_failed_callback
184
186
  @connection_failed_callback.call(connect_error)
185
187
  else
186
- Logger.error "#{@interface.name} Connection Failed: #{connect_error.class}:#{connect_error.message}"
188
+ Logger.error "#{@interface.name} Connection Failed: #{connect_error.formatted(false, false)}"
187
189
  case connect_error
188
- when Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ENOTSOCK
190
+ when Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ENOTSOCK, Errno::EHOSTUNREACH
189
191
  # Do not write an exception file for these extremely common cases
190
192
  else
191
193
  if RuntimeError === connect_error and (connect_error.message =~ /canceled/ or connect_error.message =~ /timeout/)
192
194
  # Do not write an exception file for these extremely common cases
193
195
  else
194
- Cosmos.write_exception_file(connect_error)
196
+ Logger.error connect_error.formatted
197
+ unless @connection_failed_messages.include?(connect_error.message)
198
+ Cosmos.write_exception_file(connect_error)
199
+ @connection_failed_messages << connect_error.message
200
+ end
195
201
  end
196
202
  end
197
203
  end
@@ -202,16 +208,20 @@ module Cosmos
202
208
  if @connection_lost_callback
203
209
  @connection_lost_callback.call(err)
204
210
  else
205
- Logger.info "Connection Lost for #{@interface.name}"
206
211
  if err
212
+ Logger.info "Connection Lost for #{@interface.name}: #{err.formatted(false, false)}"
207
213
  case err
208
214
  when Errno::ECONNABORTED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EBADF
209
215
  # Do not write an exception file for these extremely common cases
210
- Logger.error err.formatted(false, false)
211
216
  else
212
- Cosmos.write_exception_file(err)
213
217
  Logger.error err.formatted
218
+ unless @connection_lost_messages.include?(err.message)
219
+ Cosmos.write_exception_file(err)
220
+ @connection_lost_messages << err.message
221
+ end
214
222
  end
223
+ else
224
+ Logger.info "Connection Lost for #{@interface.name}"
215
225
  end
216
226
  end
217
227
  disconnect()
@@ -169,6 +169,13 @@ module Cosmos
169
169
  # Nothing to do if they aren't using our keywords
170
170
  formatted_command = shell_command
171
171
  end
172
+ if Kernel.is_windows?
173
+ rubyw_sub = 'rubyw'
174
+ else
175
+ rubyw_sub = 'ruby'
176
+ end
177
+
178
+ formatted_command.gsub!('RUBYW', rubyw_sub)
172
179
  formatted_command
173
180
  end
174
181
 
@@ -191,14 +198,6 @@ module Cosmos
191
198
  else
192
199
  formatted = "gnome-terminal -e \"ruby tools/#{split[1]} #{split[2..-1].join(' ')}\""
193
200
  end
194
-
195
- if Kernel.is_windows?
196
- rubyw_sub = 'rubyw'
197
- else
198
- rubyw_sub = 'ruby'
199
- end
200
-
201
- formatted.gsub!('RUBYW', rubyw_sub)
202
201
  formatted
203
202
  end
204
203
 
@@ -25,6 +25,15 @@ require 'cosmos/io/stderr'
25
25
 
26
26
  module Cosmos
27
27
 
28
+ Cosmos.disable_warnings do
29
+ module Script
30
+ def prompt_for_script_abort
31
+ ScriptRunnerFrame.instance.perform_pause
32
+ return false # Not aborted - Retry
33
+ end
34
+ end
35
+ end
36
+
28
37
  class ScriptRunnerDialog < Qt::Dialog
29
38
  attr_reader :script_runner_frame
30
39
 
@@ -428,11 +428,15 @@ module Cosmos
428
428
 
429
429
  # TODO: This can take a while depending on the number of tests and their
430
430
  # complexity. Consider making a progress bar for this.
431
- require_utilities()
432
- handle_check_buttons()
433
- @script_runner_frame.stop_message_log
434
- yield
435
- @script_runner_frame.run
431
+ begin
432
+ require_utilities()
433
+ handle_check_buttons()
434
+ @script_runner_frame.stop_message_log
435
+ yield
436
+ @script_runner_frame.run
437
+ rescue Exception => error
438
+ ExceptionDialog.new(self, error, "Error starting test", false)
439
+ end
436
440
  end
437
441
 
438
442
  def handle_start(test_suite, test = nil, test_case = nil)
@@ -16,6 +16,7 @@ require 'open3'
16
16
  require 'cosmos/core_ext'
17
17
  require 'cosmos/version'
18
18
  require 'cosmos/utilities/logger'
19
+ require 'socket'
19
20
 
20
21
  # If a hazardous command is sent through the {Cosmos::Api} this error is raised.
21
22
  # {Cosmos::Script} rescues the error and prompts the user to continue.
@@ -642,7 +643,7 @@ module Cosmos
642
643
  end
643
644
  if thread.alive?
644
645
  # Graceful failed
645
- Logger.warn "Failed to gracefully kill thread:\n #{thread.backtrace.join("\n ")}\n"
646
+ Logger.warn "Failed to gracefully kill thread:\n Caller Backtrace:\n #{caller().join("\n ")}\n \n Thread Backtrace:\n #{thread.backtrace.join("\n ")}\n\n"
646
647
  thread.kill
647
648
  end_time = Time.now + hard_timeout
648
649
  while thread.alive? && ((end_time - Time.now) > 0)
@@ -655,4 +656,25 @@ module Cosmos
655
656
  end
656
657
  end
657
658
 
659
+ # Close a socket in a manner that ensures that any reads blocked in select
660
+ # will unblock across platforms
661
+ # @param socket The socket to close
662
+ def self.close_socket(socket)
663
+ if socket
664
+ # Calling shutdown and then sleep seems to be required
665
+ # to get select to reliably unblock on linux
666
+ begin
667
+ socket.shutdown(:RDWR)
668
+ sleep(0)
669
+ rescue Exception
670
+ # Oh well we tried
671
+ end
672
+ begin
673
+ socket.close unless socket.closed?
674
+ rescue Exception
675
+ # Oh well we tried
676
+ end
677
+ end
678
+ end
679
+
658
680
  end
@@ -1,12 +1,12 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- COSMOS_VERSION = '3.2.0'
3
+ COSMOS_VERSION = '3.2.1'
4
4
  module Cosmos
5
5
  module Version
6
6
  MAJOR = '3'
7
7
  MINOR = '2'
8
- PATCH = '0'
9
- BUILD = '29c04013a08ebeab57b88412820e0cd79782c49f'
8
+ PATCH = '1'
9
+ BUILD = '3b192982d9c44a1e0bef7c7a1d8c730d17a5beb3'
10
10
  end
11
- VERSION = '3.2.0'
11
+ VERSION = '3.2.1'
12
12
  end
@@ -70,14 +70,13 @@ module Cosmos
70
70
  cmd("INST COLLECT with TYPE SPECIAL")
71
71
 
72
72
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
73
- stdout.string.should match /cmd\(\'INST COLLECT/
73
+ stdout.string.should match /cmd\(\'INST COLLECT/ # '
74
74
  stdout.rewind
75
75
 
76
76
  expect(self).to receive(:gets) { 'n' } # Don't send hazardous
77
- expect(self).to receive(:gets) { 'n' } # Don't stop running script
77
+ expect(self).to receive(:gets) { 'y' } # Stop running script
78
78
  cmd("INST COLLECT with TYPE SPECIAL")
79
79
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
80
- stdout.string.should match "WARN: Hazardous command not sent"
81
80
  end
82
81
  end
83
82
  end
@@ -93,14 +92,13 @@ module Cosmos
93
92
  cmd_no_range_check("INST COLLECT with TYPE SPECIAL")
94
93
 
95
94
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
96
- stdout.string.should match /cmd\(\'INST COLLECT/
95
+ stdout.string.should match /cmd\(\'INST COLLECT/ # '
97
96
  stdout.rewind
98
97
 
99
98
  expect(self).to receive(:gets) { 'n' } # Don't send hazardous
100
- expect(self).to receive(:gets) { 'n' } # Don't stop running script
99
+ expect(self).to receive(:gets) { 'y' } # Stop running script
101
100
  cmd_no_range_check("INST COLLECT with TYPE SPECIAL")
102
101
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
103
- stdout.string.should match "WARN: Hazardous command not sent"
104
102
  end
105
103
  end
106
104
  end
@@ -115,7 +113,7 @@ module Cosmos
115
113
  cmd_no_hazardous_check("INST COLLECT with TYPE SPECIAL")
116
114
 
117
115
  stdout.string.should match "Command INST COLLECT being sent ignoring hazardous warnings"
118
- stdout.string.should match /cmd\(\'INST COLLECT/
116
+ stdout.string.should match /cmd\(\'INST COLLECT/ # '
119
117
  end
120
118
  end
121
119
  end
@@ -126,7 +124,7 @@ module Cosmos
126
124
  cmd_no_checks("INST COLLECT with TYPE SPECIAL, DURATION 20")
127
125
 
128
126
  stdout.string.should match "Command INST COLLECT being sent ignoring hazardous warnings"
129
- stdout.string.should match /cmd\(\'INST COLLECT/
127
+ stdout.string.should match /cmd\(\'INST COLLECT/ # '
130
128
  end
131
129
  end
132
130
  end
@@ -135,12 +133,12 @@ module Cosmos
135
133
  it "should send a command" do
136
134
  capture_io do |stdout|
137
135
  cmd_raw("INST ABORT")
138
- stdout.string.should match /cmd_raw\(\'INST ABORT\'\)/
136
+ stdout.string.should match /cmd_raw\(\'INST ABORT\'\)/ # '
139
137
  end
140
138
  end
141
139
 
142
140
  it "should check parameter ranges" do
143
- expect { cmd_raw("INST COLLECT with TYPE 0, DURATION 20") }.to raise_error(/Command parameter 'INST COLLECT DURATION' = 20 not in valid range/) #'
141
+ expect { cmd_raw("INST COLLECT with TYPE 0, DURATION 20") }.to raise_error(/Command parameter 'INST COLLECT DURATION' = 20 not in valid range/) # '
144
142
  end
145
143
 
146
144
  it "should prompt for a hazardous command" do
@@ -149,14 +147,13 @@ module Cosmos
149
147
  cmd_raw("INST COLLECT with TYPE 1")
150
148
 
151
149
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
152
- stdout.string.should match /cmd_raw\(\'INST COLLECT/
150
+ stdout.string.should match /cmd_raw\(\'INST COLLECT/ # '
153
151
  stdout.rewind
154
152
 
155
153
  expect(self).to receive(:gets) { 'n' } # Don't send hazardous
156
- expect(self).to receive(:gets) { 'n' } # Don't stop running script
154
+ expect(self).to receive(:gets) { 'y' } # Stop running script
157
155
  cmd_raw("INST COLLECT with TYPE 1")
158
156
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
159
- stdout.string.should match "WARN: Hazardous command not sent"
160
157
  end
161
158
  end
162
159
  end
@@ -172,14 +169,13 @@ module Cosmos
172
169
  cmd_raw_no_range_check("INST COLLECT with TYPE 1")
173
170
 
174
171
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
175
- stdout.string.should match /cmd_raw\(\'INST COLLECT/
172
+ stdout.string.should match /cmd_raw\(\'INST COLLECT/ # '
176
173
  stdout.rewind
177
174
 
178
175
  expect(self).to receive(:gets) { 'n' } # Don't send hazardous
179
- expect(self).to receive(:gets) { 'n' } # Don't stop running script
176
+ expect(self).to receive(:gets) { 'y' } # Stop running script
180
177
  cmd_raw_no_range_check("INST COLLECT with TYPE 1")
181
178
  stdout.string.should match "Warning: Command INST COLLECT is Hazardous"
182
- stdout.string.should match "WARN: Hazardous command not sent"
183
179
  end
184
180
  end
185
181
  end
@@ -361,6 +361,28 @@ module Cosmos
361
361
  end
362
362
  end
363
363
 
364
+ context "with two interfaces with the same name" do
365
+ it "should complain about duplicate interface names" do
366
+ tf = Tempfile.new('unittest')
367
+ tf.puts "INTERFACE CtsConfigTestInterface cts_config_test_interface.rb"
368
+ tf.puts "INTERFACE CtsConfigTestInterface cts_config_test_interface.rb"
369
+ tf.close
370
+ expect { CmdTlmServerConfig.new(tf.path) }.to raise_error(ConfigParser::Error, "Interface 'CTSCONFIGTESTINTERFACE' defined twice")
371
+ tf.unlink
372
+ end
373
+ end
374
+
375
+ context "with two routers with the same name" do
376
+ it "should complain about duplicate router names" do
377
+ tf = Tempfile.new('unittest')
378
+ tf.puts "ROUTER MY_ROUTER1 cts_config_test_interface.rb"
379
+ tf.puts "ROUTER MY_ROUTER1 cts_config_test_interface.rb"
380
+ tf.close
381
+ expect { CmdTlmServerConfig.new(tf.path) }.to raise_error(ConfigParser::Error, "Router 'MY_ROUTER1' defined twice")
382
+ tf.unlink
383
+ end
384
+ end
385
+
364
386
  context "with ROUTER" do
365
387
  it "should create a new router" do
366
388
  tf = Tempfile.new('unittest')
@@ -64,7 +64,7 @@ module Cosmos
64
64
  sleep 0.2
65
65
  Thread.list.length.should eql(1)
66
66
 
67
- stdout.string.should match "Connection Failed: RuntimeError:ConnectError"
67
+ stdout.string.should match "Connection Failed: RuntimeError : ConnectError"
68
68
  end
69
69
  end
70
70
 
@@ -274,7 +274,11 @@ module Cosmos
274
274
  if Kernel.is_mac? and File.exist?(File.join(USERPATH, 'tools', 'mac'))
275
275
  expect(lc.items[0][2]).to eq 'open tools/mac/CmdTlmServer.app --args --system system.txt -x 0 -y 0'
276
276
  else
277
- expect(lc.items[0][2]).to eq 'RUBYW tools/CmdTlmServer --system system.txt -x 0 -y 0'
277
+ if Kernel.is_windows?
278
+ expect(lc.items[0][2]).to eq 'rubyw tools/CmdTlmServer --system system.txt -x 0 -y 0'
279
+ else
280
+ expect(lc.items[0][2]).to eq 'ruby tools/CmdTlmServer --system system.txt -x 0 -y 0'
281
+ end
278
282
  end
279
283
  expect(lc.items[0][3]).to be true
280
284
  expect(lc.items[0][4]).to be_nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cosmos
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Melton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-17 00:00:00.000000000 Z
12
+ date: 2015-02-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -616,6 +616,7 @@ files:
616
616
  - data/COSMOS_64x64.bmp
617
617
  - data/COSMOS_64x64.ico
618
618
  - data/COSMOS_64x64.png
619
+ - data/COSMOS_Architecture.png
619
620
  - data/CheckBoxCheck.gif
620
621
  - data/CheckBoxEmpty.gif
621
622
  - data/Earthmap1024x512.gif