Skip to content

Add lab restart command and 1BRC validators#15

Merged
thearyanahmed merged 15 commits into
masterfrom
v0.9-reset-project-and-improved-validator
Jan 31, 2026
Merged

Add lab restart command and 1BRC validators#15
thearyanahmed merged 15 commits into
masterfrom
v0.9-reset-project-and-improved-validator

Conversation

@thearyanahmed

Copy link
Copy Markdown
Owner

No description provided.

Implements two validators for performance challenges:
- output_match: runs command, compares stdout to expected file
- benchmark: validates output correctness and execution time

Both validators support workspace detection from active lab state.
Adds factory methods and RuntimeValidator enum variants:
- output_match:string(cmd),string(expected_file)
- benchmark:string(cmd),string(expected_file),int(max_ms)

Includes unit tests for DSL parsing.
@thearyanahmed thearyanahmed changed the title wip Add lab restart command and 1BRC validators Jan 31, 2026
@thearyanahmed thearyanahmed requested a review from Copilot January 31, 2026 14:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a lab restart command and introduces benchmark validators for performance-focused challenges like the 1 Billion Row Challenge (1BRC). The restart functionality allows users to reset their progress on a lab while maintaining their workspace, and the new validators enable correctness checking and performance benchmarking of command outputs.

Changes:

  • Added luxctl lab restart command with API integration
  • Implemented OutputMatchValidator and BenchmarkValidator for comparing command outputs against expected files
  • Added comprehensive E2E test suite covering authentication, lab lifecycle, and task operations

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/commands/lab.rs Implements restart command handling with server synchronization
src/api/client.rs Adds restart_lab API endpoint
src/api/types.rs Defines RestartLabResponse and RestartLabData types
src/state.rs Adds clear_progress method to reset task status
src/main.rs Adds Restart action to CLI
src/validators/benchmark.rs New module with output matching and benchmarking validators
src/validators/factory.rs Registers new validators and factory functions
src/validators/mod.rs Exports new benchmark validators
tests/e2e.rs New E2E test suite for local API testing
src/lib.rs Version bump to 0.7.0
Cargo.toml Version bump to 0.7.0

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/e2e.rs Outdated
let out = stdout(&output);
// should show user email or name
assert!(
out.contains("@") || out.len() > 0,

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition out.len() > 0 is redundant and always true when combined with ||. Use !out.is_empty() as the second condition, or if any non-empty output is acceptable, simplify to just that check.

Suggested change
out.contains("@") || out.len() > 0,
!out.is_empty(),

Copilot uses AI. Check for mistakes.
Comment thread src/validators/benchmark.rs Outdated
Comment on lines +14 to +28
fn get_workspace() -> PathBuf {
let config = match Config::load() {
Ok(c) => c,
Err(_) => return std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
};
if !config.has_auth_token() {
return std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
}
let state = match LabState::load(config.expose_token()) {
Ok(s) => s,
Err(_) => return std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
};
match state.get_active() {
Some(lab) => PathBuf::from(&lab.workspace),
None => std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback std::env::current_dir().unwrap_or_else(|_| PathBuf::from(\".\")) is duplicated in lines 17, 20, 24, and 28. Extract this into a helper function or constant to improve maintainability.

Suggested change
fn get_workspace() -> PathBuf {
let config = match Config::load() {
Ok(c) => c,
Err(_) => return std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
};
if !config.has_auth_token() {
return std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
}
let state = match LabState::load(config.expose_token()) {
Ok(s) => s,
Err(_) => return std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
};
match state.get_active() {
Some(lab) => PathBuf::from(&lab.workspace),
None => std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
fn current_dir_or_dot() -> PathBuf {
std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."))
}
fn get_workspace() -> PathBuf {
let config = match Config::load() {
Ok(c) => c,
Err(_) => return current_dir_or_dot(),
};
if !config.has_auth_token() {
return current_dir_or_dot();
}
let state = match LabState::load(config.expose_token()) {
Ok(s) => s,
Err(_) => return current_dir_or_dot(),
};
match state.get_active() {
Some(lab) => PathBuf::from(&lab.workspace),
None => current_dir_or_dot(),

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +40
let parts: Vec<&str> = cmd_str.split_whitespace().collect();
if parts.is_empty() {
return Err("empty command".to_string());
}

let program = parts[0];
let args = &parts[1..];

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using split_whitespace() for command parsing doesn't handle quoted arguments (e.g., paths with spaces). Consider using a proper shell-like parser or document this limitation, especially since this is used for benchmark commands that may reference file paths.

Copilot uses AI. Check for mistakes.
Comment thread src/validators/benchmark.rs Outdated
let expected_lines: Vec<&str> = expected.lines().collect();

let mut diff_msg = String::new();
for (i, (a, e)) in actual_lines.iter().zip(expected_lines.iter()).enumerate() {

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diff generation logic in lines 120-130 and 187-196 is duplicated between OutputMatchValidator and BenchmarkValidator. Extract this into a shared helper function to reduce code duplication.

Copilot uses AI. Check for mistakes.
Replace verbose email-checking logic with simple empty check
since any user info indicates success.
Extract current_dir_fallback() to reduce duplication in get_workspace().
Extract diff_preview() to consolidate duplicate diff generation logic.
Add comment documenting split_whitespace limitation in run_command().
@thearyanahmed thearyanahmed requested a review from Copilot January 31, 2026 14:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 29 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/e2e.rs
const API_BASE_URL: &str = "http://0.0.0.0:8000";

fn get_test_token() -> Option<String> {
// try dev_token file first (gitignored, local dev)

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization and improved comment clarity for 'try dev_token file first' to 'Try dev_token file first'.

Suggested change
// try dev_token file first (gitignored, local dev)
// Try dev_token file first (gitignored, local dev)

Copilot uses AI. Check for mistakes.
Comment thread tests/e2e.rs
}
}

// fallback to env var

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'fallback to env var' to 'Fallback to env var'.

Suggested change
// fallback to env var
// Fallback to env var

Copilot uses AI. Check for mistakes.
Comment thread tests/e2e.rs
}

fn luxctl_with_token(args: &[&str], token: &str) -> Output {
// first authenticate, then run command

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'first authenticate, then run command' to 'First authenticate, then run command'.

Suggested change
// first authenticate, then run command
// First authenticate, then run command

Copilot uses AI. Check for mistakes.
Comment thread tests/e2e.rs
String::from_utf8_lossy(&output.stderr).to_string()
}

// helper to check if local API is running

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'helper to check if local API is running' to 'Helper to check if local API is running'.

Suggested change
// helper to check if local API is running
// Helper to check if local API is running

Copilot uses AI. Check for mistakes.
Comment thread tests/e2e.rs

let output = luxctl(&["auth", "--token", "invalid-token-12345"]);

// should fail gracefully

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'should fail gracefully' to 'Should fail gracefully'.

Suggested change
// should fail gracefully
// Should fail gracefully

Copilot uses AI. Check for mistakes.
String::new()
}

/// truncate string for display

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'truncate string for display' to 'Truncate string for display'.

Suggested change
/// truncate string for display
/// Truncate string for display

Copilot uses AI. Check for mistakes.
let actual = normalize(&stdout);
let expected = normalize(&expected);

// first check correctness

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'first check correctness' to 'First check correctness'.

Suggested change
// first check correctness
// First check correctness

Copilot uses AI. Check for mistakes.
});
}

// then check timing

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'then check timing' to 'Then check timing'.

Suggested change
// then check timing
// Then check timing

Copilot uses AI. Check for mistakes.
Comment thread src/commands/lab.rs

match client.restart_lab(&lab.slug).await {
Ok(response) => {
// refresh tasks from server

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'refresh tasks from server' to 'Refresh tasks from server'.

Suggested change
// refresh tasks from server
// Refresh tasks from server

Copilot uses AI. Check for mistakes.
Comment thread src/commands/lab.rs
state.save(config.expose_token())?;
}
Err(_) => {
// if refresh fails, just clear local progress

Copilot AI Jan 31, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected capitalization for 'if refresh fails, just clear local progress' to 'If refresh fails, just clear local progress'.

Suggested change
// if refresh fails, just clear local progress
// If refresh fails, just clear local progress

Copilot uses AI. Check for mistakes.
@thearyanahmed thearyanahmed merged commit d97517a into master Jan 31, 2026
1 check passed
@thearyanahmed thearyanahmed deleted the v0.9-reset-project-and-improved-validator branch March 24, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants