From 980565c201fdb5936af0bef9ac35907a58fbade1 Mon Sep 17 00:00:00 2001 From: Taylor Whatley <32211852+1whatleytay@users.noreply.github.com> Date: Sat, 13 Jan 2024 11:09:17 -0500 Subject: [PATCH 1/2] Add rust autotest db example --- .../rust/script_files/src/lib.rs | 2 + .../rust/script_files/src/tests.rs | 48 ++++++++++++++++++ db/data/autotest_files/rust/specs.json | 20 ++++++++ .../rust/student_files/Cargo.toml | 8 +++ .../rust/student_files/src/lib.rs | 1 + .../rust/student_files/src/queue.rs | 49 +++++++++++++++++++ lib/tasks/autotest.rake | 34 +++++++++---- 7 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 db/data/autotest_files/rust/script_files/src/lib.rs create mode 100644 db/data/autotest_files/rust/script_files/src/tests.rs create mode 100644 db/data/autotest_files/rust/specs.json create mode 100644 db/data/autotest_files/rust/student_files/Cargo.toml create mode 100644 db/data/autotest_files/rust/student_files/src/lib.rs create mode 100644 db/data/autotest_files/rust/student_files/src/queue.rs diff --git a/db/data/autotest_files/rust/script_files/src/lib.rs b/db/data/autotest_files/rust/script_files/src/lib.rs new file mode 100644 index 0000000000..426180c031 --- /dev/null +++ b/db/data/autotest_files/rust/script_files/src/lib.rs @@ -0,0 +1,2 @@ +mod queue; +mod tests; diff --git a/db/data/autotest_files/rust/script_files/src/tests.rs b/db/data/autotest_files/rust/script_files/src/tests.rs new file mode 100644 index 0000000000..1890cb2630 --- /dev/null +++ b/db/data/autotest_files/rust/script_files/src/tests.rs @@ -0,0 +1,48 @@ +#[cfg(test)] +mod tests { + use crate::queue::MyQueue; + + #[test] + pub fn test_dequeue_empty() { + let mut queue: MyQueue = MyQueue::new(); + + assert!(queue.dequeue().is_none()); + } + + #[test] + pub fn test_enqueue_size() { + let mut queue: MyQueue = MyQueue::new(); + + assert!(queue.enqueue(4).is_some()); + assert_eq!(queue.size(), 1); + } + + #[test] + pub fn test_enqueue_dequeue_value() { + let mut queue: MyQueue = MyQueue::new(); + + assert!(queue.enqueue(4).is_some()); + assert_eq!(queue.dequeue(), Some(4)); + } + + #[test] + pub fn test_enqueue_dequeue_many_values() { + let mut queue: MyQueue = MyQueue::new(); + + assert!(queue.enqueue(4).is_some()); + assert!(queue.enqueue(5).is_some()); + assert_eq!(queue.dequeue(), Some(4)); + assert_eq!(queue.dequeue(), Some(5)); + } + + #[test] + pub fn test_queue_full() { + let mut queue: MyQueue = MyQueue::new(); + + assert!(queue.enqueue(4).is_some()); + assert!(queue.enqueue(5).is_some()); + assert!(queue.enqueue(6).is_none()); + + assert_eq!(queue.size(), 2); + } +} diff --git a/db/data/autotest_files/rust/specs.json b/db/data/autotest_files/rust/specs.json new file mode 100644 index 0000000000..8b20cb8f97 --- /dev/null +++ b/db/data/autotest_files/rust/specs.json @@ -0,0 +1,20 @@ +{ + "testers": [ + { + "tester_type": "rust", + "test_data": [ + { + "script_files": ["src/tests.rs"], + "category": [ + "instructor" + ], + "timeout": 30, + "extra_info": { + "criterion": "criterion", + "name": "Rust Test Group" + } + } + ] + } + ] +} diff --git a/db/data/autotest_files/rust/student_files/Cargo.toml b/db/data/autotest_files/rust/student_files/Cargo.toml new file mode 100644 index 0000000000..39e3e72911 --- /dev/null +++ b/db/data/autotest_files/rust/student_files/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "test-time" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/db/data/autotest_files/rust/student_files/src/lib.rs b/db/data/autotest_files/rust/student_files/src/lib.rs new file mode 100644 index 0000000000..ae2004c853 --- /dev/null +++ b/db/data/autotest_files/rust/student_files/src/lib.rs @@ -0,0 +1 @@ +mod queue; diff --git a/db/data/autotest_files/rust/student_files/src/queue.rs b/db/data/autotest_files/rust/student_files/src/queue.rs new file mode 100644 index 0000000000..41c3577c54 --- /dev/null +++ b/db/data/autotest_files/rust/student_files/src/queue.rs @@ -0,0 +1,49 @@ +pub struct MyQueue { + count: usize, + start: usize, + buffer: [Option; N] // We could use MaybeUninit here instead. +} + +impl MyQueue { + pub fn new() -> MyQueue { + // Fill array with None (we don't have Copy + Clone so buffer: [None; N] is no good!) + MyQueue { + count: 0, + start: 0, + buffer: std::array::from_fn(|_| None) + } + } + + pub fn enqueue(&mut self, value: T) -> Option<()> { + if self.count >= N { + return None + } + + let end = (self.start + self.count) % N; + + self.buffer[end] = Some(value); + + self.count += 1; + + Some(()) + } + + pub fn dequeue(&mut self) -> Option { + if self.count <= 0 { + return None + } + + let value = self.buffer[self.start].take(); + + self.count -= 1; + + // Intentional error for tests to catch. + // self.start += 1; + + value + } + + pub fn size(&self) -> usize { + self.count + } +} diff --git a/lib/tasks/autotest.rake b/lib/tasks/autotest.rake index fe7078e069..58494e1d88 100644 --- a/lib/tasks/autotest.rake +++ b/lib/tasks/autotest.rake @@ -39,8 +39,8 @@ class AutotestSetup def initialize(root_dir) # setup instance variables (mostly paths to directories) @assg_short_id = "autotest_#{File.basename(root_dir)}" - script_dir = File.join(root_dir, 'script_files') - @test_scripts = Dir.glob(File.join(script_dir, '*')) + @script_dir = File.join(root_dir, 'script_files') + @test_scripts = Dir.glob(File.join(@script_dir, '*')) @specs_file = File.join(root_dir, 'specs.json') @specs_data = JSON.parse(File.read(@specs_file)) @@ -102,8 +102,10 @@ class AutotestSetup test_file_destination = @assignment.autotest_files_dir FileUtils.makedirs test_file_destination + return unless File.directory?(@script_dir) + # copy test scripts and specs files into the destination directory - FileUtils.cp @test_scripts, test_file_destination + FileUtils.copy_entry @script_dir, test_file_destination end def create_marking_scheme @@ -127,6 +129,24 @@ class AutotestSetup ) end + def create_submission_files(transaction, glob) + glob.each do |file_path| + if File.directory?(file_path) + transaction.add_path(file_path) + + next_glob = Dir.glob(File.join(file_path, '*')) + + create_submission_files(transaction, next_glob) + else + File.open(file_path, 'r') do |file| + file_rel_path = Pathname.new(file_path).relative_path_from Pathname.new(@student_dir) + repo_path = File.join(@assignment.repository_folder, file_rel_path) + transaction.add(repo_path, file.read, '') + end + end + end + end + def create_submission return if @assignment.groupings.exists? @@ -136,13 +156,7 @@ class AutotestSetup grouping = Grouping.find_by(group_id: group, assessment_id: @assignment.id) grouping.access_repo do |repo| transaction = repo.get_transaction(student.user_name) - @student_files.each do |file_path| - File.open(file_path, 'r') do |file| - file_rel_path = Pathname.new(file_path).relative_path_from Pathname.new(@student_dir) - repo_path = File.join(@assignment.repository_folder, file_rel_path) - transaction.add(repo_path, file.read, '') - end - end + create_submission_files(transaction, @student_files) repo.commit(transaction) end # create new submission for each grouping From dd8157b394676032841ac566d10f5584af1ad180 Mon Sep 17 00:00:00 2001 From: Taylor Whatley <32211852+1whatleytay@users.noreply.github.com> Date: Sun, 14 Jan 2024 19:49:00 -0500 Subject: [PATCH 2/2] Modify Changlog for rust autotester --- Changelog.md | 1 + db/data/autotest_files/rust/specs.json | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 1692ba20f3..d87ee07b69 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ # Changelog ## [unreleased] +- Added a rust auto-test target (#6906) ## [v2.4.2] - Fix feedback file API not returning feedback file IDs correctly (#6875) diff --git a/db/data/autotest_files/rust/specs.json b/db/data/autotest_files/rust/specs.json index 8b20cb8f97..a649bd7b4d 100644 --- a/db/data/autotest_files/rust/specs.json +++ b/db/data/autotest_files/rust/specs.json @@ -4,7 +4,6 @@ "tester_type": "rust", "test_data": [ { - "script_files": ["src/tests.rs"], "category": [ "instructor" ],