1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright 2025 Lablup Inc. and Jeongkyu Shin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Tests for prompt scaling with many nodes
#[test]
fn test_prompt_with_many_nodes() {
// Test that prompt doesn't show 100 individual indicators
let node_count = 100;
let active_count = 50;
let total_connected = 100;
// Should use compact display for > 10 nodes
const MAX_INDIVIDUAL_DISPLAY: usize = 10;
assert!(node_count > MAX_INDIVIDUAL_DISPLAY);
// Format examples for many nodes
let prompt_all_active = format!("[All {total_connected}/{node_count}] bssh> ");
assert!(prompt_all_active.len() < 50); // Should be compact
let prompt_none_active = format!("[None 0/{total_connected}] bssh> ");
assert!(prompt_none_active.len() < 50);
let prompt_some_active =
format!("[Nodes 1,2,3... +47] ({active_count}/{total_connected}) bssh> ");
assert!(prompt_some_active.len() < 60);
}
#[test]
fn test_prompt_with_few_nodes() {
// Test that few nodes still show individual indicators
let node_count = 5;
const MAX_INDIVIDUAL_DISPLAY: usize = 10;
assert!(node_count <= MAX_INDIVIDUAL_DISPLAY);
// With few nodes, individual display is fine
let individual_prompt = "[● ● ● ● ●] bssh> ";
assert!(individual_prompt.len() < 30);
}
#[test]
fn test_active_nodes_display_limit() {
// Test display of active node numbers
// Case 1: 5 or fewer active nodes - show all
let active_nodes = [1, 3, 5];
let display = active_nodes
.iter()
.map(|n| n.to_string())
.collect::<Vec<_>>()
.join(",");
assert_eq!(display, "1,3,5");
// Case 2: More than 5 active nodes - show first 3 + count
let many_active = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let first_three = many_active
.iter()
.take(3)
.map(|n| n.to_string())
.collect::<Vec<_>>()
.join(",");
let display_many = format!("{first_three}... +{}", many_active.len() - 3);
assert_eq!(display_many, "1,2,3... +7");
}
#[test]
fn test_prompt_format_variations() {
// Test different prompt formats based on node states
struct TestCase {
total_nodes: usize,
#[allow(dead_code)]
total_connected: usize,
#[allow(dead_code)]
active_count: usize,
#[allow(dead_code)]
expected_pattern: &'static str,
}
let test_cases = vec![
TestCase {
total_nodes: 100,
total_connected: 100,
active_count: 100,
expected_pattern: "[All 100/100]",
},
TestCase {
total_nodes: 100,
total_connected: 95,
active_count: 0,
expected_pattern: "[None 0/95]",
},
TestCase {
total_nodes: 50,
total_connected: 48,
active_count: 3,
expected_pattern: "[Nodes", // Will show node numbers
},
TestCase {
total_nodes: 8,
total_connected: 8,
active_count: 8,
expected_pattern: "[● ● ●", // Individual display for <= 10 nodes
},
];
for tc in test_cases {
let uses_compact = tc.total_nodes > 10;
if uses_compact {
assert!(tc.total_nodes > 10);
// Compact display doesn't show individual indicators
} else {
assert!(tc.total_nodes <= 10);
// Individual display shows dots/numbers
}
}
}
#[test]
fn test_prompt_length_bounds() {
// Ensure prompt doesn't exceed reasonable length
// Worst case: many nodes with some active
let worst_case_prompt = "[Nodes 1,2,3... +997] (1000/1000) bssh> ".to_string();
// Should be under 80 characters for typical terminal width
assert!(worst_case_prompt.len() < 80);
// Best case: all active with many nodes
let best_case_prompt = "[All 1000/1000] bssh> ".to_string();
assert!(best_case_prompt.len() < 30);
}
#[test]
fn test_node_number_formatting() {
// Test formatting of node numbers in prompt
// Single digit
let single_digit = [1, 2, 3];
let formatted = single_digit
.iter()
.map(|n| n.to_string())
.collect::<Vec<_>>()
.join(",");
assert_eq!(formatted, "1,2,3");
// Multi digit
let multi_digit = [10, 50, 100];
let formatted_multi = multi_digit
.iter()
.map(|n| n.to_string())
.collect::<Vec<_>>()
.join(",");
assert_eq!(formatted_multi, "10,50,100");
}
#[test]
fn test_threshold_boundary() {
// Test behavior at the threshold boundary (10 nodes)
const MAX_INDIVIDUAL_DISPLAY: usize = 10;
// At threshold - should use individual display
assert_eq!(10, MAX_INDIVIDUAL_DISPLAY);
// Test values relative to threshold
let just_over = 11;
let just_under = 9;
// Just over threshold - should use compact display
assert!(just_over > MAX_INDIVIDUAL_DISPLAY);
// Just under threshold
assert!(just_under < MAX_INDIVIDUAL_DISPLAY);
}