Sfoglia il codice sorgente

Added some tests. Removed valuable code.

themultiplexer 8 anni fa
parent
commit
64a0359b3e

+ 27
- 16
hw6/task1/src/main.rs Vedi File

4
 extern crate nix;
4
 extern crate nix;
5
 
5
 
6
 use nix::unistd::{fork, pipe, read, write};
6
 use nix::unistd::{fork, pipe, read, write};
7
-use nix::sys::wait::wait;
7
+use nix::sys::wait::{wait, WaitStatus};
8
 use std::str;
8
 use std::str;
9
-use nix::sys::wait::WaitStatus;
10
 use nix::unistd::ForkResult::{Child, Parent};
9
 use nix::unistd::ForkResult::{Child, Parent};
11
 use std::os::unix::io::RawFd;
10
 use std::os::unix::io::RawFd;
12
 
11
 
12
+mod unit_test_pipe;
13
+
13
 const BUFFER_SIZE: usize = 256;
14
 const BUFFER_SIZE: usize = 256;
14
 
15
 
15
 
16
 
33
                                 Ok(Child) => {
34
                                 Ok(Child) => {
34
                                     match sum_strings(vec) {
35
                                     match sum_strings(vec) {
35
                                         Ok(res) => println!("Sum = {}", res),
36
                                         Ok(res) => println!("Sum = {}", res),
36
-                                        Err(e) => println!("{}", e),
37
+                                        Err(e) => {
38
+                                            println!("{}", e);
39
+                                            process::exit(1);
40
+                                        }
37
                                     }
41
                                     }
38
                                 }
42
                                 }
39
                                 Ok(Parent { .. }) => {
43
                                 Ok(Parent { .. }) => {
40
                                     if let Ok(ws) = wait() {
44
                                     if let Ok(ws) = wait() {
41
-                                        if let WaitStatus::Exited(_, _) = ws {
45
+                                        if let WaitStatus::Exited(_, exit_code) = ws {
42
                                             match mul_strings(vec) {
46
                                             match mul_strings(vec) {
43
                                                 Ok(res) => println!("Mul = {}", res),
47
                                                 Ok(res) => println!("Mul = {}", res),
44
-                                                Err(e) => println!("{}", e),
48
+                                                Err(e) => {
49
+                                                    println!("{}", e);
50
+                                                    process::exit(1);
51
+                                                }
45
                                             }
52
                                             }
53
+                                            process::exit(exit_code as i32);
46
                                         }
54
                                         }
47
                                     }
55
                                     }
48
                                 }
56
                                 }
59
                     for s in numbers {
67
                     for s in numbers {
60
                         args = concatenate_strings(&args, &concatenate_strings(&s, " "));
68
                         args = concatenate_strings(&args, &concatenate_strings(&s, " "));
61
                     }
69
                     }
62
-                    println!("sending to children: {}", args);
70
+                    println!("sending to childs: {}", args);
71
+
63
                     if let Err(_) = write(writer, args.as_bytes()) {
72
                     if let Err(_) = write(writer, args.as_bytes()) {
64
                         println!("Broken pipe")
73
                         println!("Broken pipe")
65
                     }
74
                     }
66
 
75
 
67
-                    if let Err(_) = wait() {
68
-                        println!("Waiting on children failed")
76
+                    if let Ok(ws) = wait() {
77
+                        if let WaitStatus::Exited(_, exit_code) = ws {
78
+                            process::exit(exit_code as i32);
79
+                        }
69
                     }
80
                     }
70
                 }
81
                 }
71
 
82
 
106
 }
117
 }
107
 
118
 
108
 /// Calculates the sum of the given Strings and returns them as a Result.
119
 /// Calculates the sum of the given Strings and returns them as a Result.
109
-fn sum_strings(v: Vec<String>) -> Result<i32, String> {
110
-    let mut sum = 0;
120
+fn sum_strings(v: Vec<String>) -> Result<i64, String> {
121
+    let mut sum: i64 = 0;
111
     for x in v {
122
     for x in v {
112
-        match x.parse::<i32>() {
123
+        match x.parse::<i64>() {
113
             Ok(val) => {
124
             Ok(val) => {
114
-                match i32::checked_add(sum, val) {
125
+                match i64::checked_add(sum, val) {
115
                     Some(y) => {
126
                     Some(y) => {
116
                         sum = y;
127
                         sum = y;
117
                     }
128
                     }
125
 }
136
 }
126
 
137
 
127
 /// Calculates the product of the given Strings and returns them as a Result.
138
 /// Calculates the product of the given Strings and returns them as a Result.
128
-fn mul_strings(v: Vec<String>) -> Result<i32, String> {
129
-    let mut prod = 1;
139
+fn mul_strings(v: Vec<String>) -> Result<i64, String> {
140
+    let mut prod: i64 = 1;
130
     for x in v {
141
     for x in v {
131
-        match x.parse::<i32>() {
142
+        match x.parse::<i64>() {
132
             Ok(val) => {
143
             Ok(val) => {
133
-                match i32::checked_mul(prod, val) {
144
+                match i64::checked_mul(prod, val) {
134
                     Some(y) => {
145
                     Some(y) => {
135
                         prod = y;
146
                         prod = y;
136
                     }
147
                     }

+ 24
- 0
hw6/task1/src/unit_test_pipe.rs Vedi File

1
+#[cfg(test)]
2
+mod test {
3
+    use read_from_pipe;
4
+    use nix::unistd::{pipe, write};
5
+
6
+    #[test]
7
+    fn test_pipe() {
8
+        match pipe() {
9
+            Ok((reader, writer)) => {
10
+                let input = b"teststring";
11
+
12
+                if let Err(_) = write(writer, input) {
13
+                    // Broken pipe
14
+                }
15
+                assert_eq!(read_from_pipe(reader).unwrap(), "teststring".to_string());
16
+            }
17
+            Err(_) => {}
18
+        }
19
+
20
+    }
21
+
22
+    #[test]
23
+    fn test_kill_last_child() {}
24
+}

+ 5
- 1
hw6/task2/src/command.rs Vedi File

2
 use std::str::FromStr;
2
 use std::str::FromStr;
3
 use std::env;
3
 use std::env;
4
 
4
 
5
+#[derive(PartialEq, Debug)]
5
 pub enum Command {
6
 pub enum Command {
6
     Empty,
7
     Empty,
7
     Exit,
8
     Exit,
8
     Cd(Option<OsString>),
9
     Cd(Option<OsString>),
9
 }
10
 }
10
 
11
 
12
+#[derive(PartialEq, Debug)]
11
 pub struct CommandNotFoundError;
13
 pub struct CommandNotFoundError;
12
 
14
 
13
 impl FromStr for Command {
15
 impl FromStr for Command {
31
 
33
 
32
 
34
 
33
 impl Command {
35
 impl Command {
34
-    /// If the passed String exists, set the path of the Cd in the enum
36
+    /// If the passed String exists, set the path of the Cd in the enum (as OsString)
37
+    /// Returns **Command**
35
     pub fn parse_cd(cmd: Option<&str>) -> Self {
38
     pub fn parse_cd(cmd: Option<&str>) -> Self {
36
         match cmd {
39
         match cmd {
37
             None => Command::Cd(None),
40
             None => Command::Cd(None),
39
         }
42
         }
40
     }
43
     }
41
 
44
 
45
+    /// If this instance is of Kind **Command::Cd** either go to HOME or navigate to the given path
42
     pub fn exec_cd(&self) {
46
     pub fn exec_cd(&self) {
43
         if let Command::Cd(None) = *self {
47
         if let Command::Cd(None) = *self {
44
             let possible_home = env::home_dir();
48
             let possible_home = env::home_dir();

+ 4
- 5
hw6/task2/src/main.rs Vedi File

1
 use std::process;
1
 use std::process;
2
-use shell::{Shell, R, W};
2
+use shell::Shell;
3
 use std::io;
3
 use std::io;
4
 
4
 
5
+mod unit_tests_shell;
5
 mod command;
6
 mod command;
6
 mod shell;
7
 mod shell;
7
 
8
 
8
 
9
 
10
+
9
 fn main() {
11
 fn main() {
10
     let stdin = io::stdin();
12
     let stdin = io::stdin();
11
-    let input = R(stdin.lock());
12
-
13
     let stdout = io::stdout();
13
     let stdout = io::stdout();
14
-    let output = W(stdout.lock());
15
 
14
 
16
-    let mut s = Shell::new(input, output, "schell".to_string());
15
+    let mut s = Shell::new(stdin.lock(), stdout.lock(), "schell".to_string());
17
     match s.start() {
16
     match s.start() {
18
         Ok(_) => process::exit(0),
17
         Ok(_) => process::exit(0),
19
         Err(_) => process::exit(1),
18
         Err(_) => process::exit(1),

+ 8
- 46
hw6/task2/src/shell.rs Vedi File

1
-use std::io::{BufRead, Write, Read, StdinLock, StdoutLock};
2
-use std::io;
3
-
1
+use std::io::{BufRead, Write};
4
 use command::*;
2
 use command::*;
5
 use std::str::FromStr;
3
 use std::str::FromStr;
6
 use std::env;
4
 use std::env;
7
 
5
 
8
-///Tuple-Structs which hold Std-in and -out locks.
9
-pub struct R<'a>(pub StdinLock<'a>);
10
-pub struct W<'a>(pub StdoutLock<'a>);
11
-
12
-pub struct Shell<R, W> {
6
+pub struct Shell<R: BufRead, W: Write> {
13
     pub reader: R,
7
     pub reader: R,
14
     pub writer: W,
8
     pub writer: W,
15
     pub should_exit: bool,
9
     pub should_exit: bool,
16
     pub name: String,
10
     pub name: String,
17
 }
11
 }
18
 
12
 
19
-impl<'a> Shell<R<'a>, W<'a>> {
13
+impl<R: BufRead, W: Write> Shell<R, W> {
20
     /// Creates a new Shell with a name, input and output.
14
     /// Creates a new Shell with a name, input and output.
21
-    pub fn new(input: R<'a>, output: W<'a>, name: String) -> Self {
15
+    pub fn new(input: R, output: W, name: String) -> Self {
22
         Shell {
16
         Shell {
23
             reader: input,
17
             reader: input,
24
             writer: output,
18
             writer: output,
37
     /// If the Command-creation succeeds, run the command.
31
     /// If the Command-creation succeeds, run the command.
38
     fn shell_loop(&mut self) -> Result<(), &str> {
32
     fn shell_loop(&mut self) -> Result<(), &str> {
39
         while !self.should_exit {
33
         while !self.should_exit {
40
-            if let Ok(line) = self.prompt() {
34
+            if let Ok(Some(line)) = self.prompt() {
41
                 let _ = Command::from_str(&line).and_then(|cmd| self.run(cmd));
35
                 let _ = Command::from_str(&line).and_then(|cmd| self.run(cmd));
42
             }
36
             }
43
         }
37
         }
46
 
40
 
47
     /// Prints the shell prompt.
41
     /// Prints the shell prompt.
48
     /// Waits for user input and returns the read line.
42
     /// Waits for user input and returns the read line.
49
-    fn prompt(&mut self) -> Result<String, &str> {
43
+    pub fn prompt(&mut self) -> Result<Option<String>, &str> {
50
         match env::current_dir() {
44
         match env::current_dir() {
51
             Ok(pwd) => {
45
             Ok(pwd) => {
52
                 let _ = self.writer.write(
46
                 let _ = self.writer.write(
58
                 let mut line: String = String::new();
52
                 let mut line: String = String::new();
59
                 let read_result = self.reader.read_line(&mut line);
53
                 let read_result = self.reader.read_line(&mut line);
60
                 match read_result {
54
                 match read_result {
61
-                    Ok(_) => Ok(line),
62
-                    Err(_) => Err("Error reading."),
55
+                    Ok(_) => Ok(Some(line)),
56
+                    Err(_) => Ok(None),
63
                 }
57
                 }
64
             }
58
             }
65
             Err(_) => return Err("Path Error"),
59
             Err(_) => return Err("Path Error"),
80
         Ok(())
74
         Ok(())
81
     }
75
     }
82
 }
76
 }
83
-
84
-/// Implement Read-Trait for Tuple-Struct R
85
-/// Simply calls `read` of StdinLock
86
-impl<'a> Read for R<'a> {
87
-    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
88
-        self.0.read(buf)
89
-    }
90
-}
91
-
92
-/// Implement BufRead-Trait for Tuple-Struct R
93
-/// Simply calls `fill_buff` and `consume` from StdinLock
94
-impl<'a> BufRead for R<'a> {
95
-    fn fill_buf(&mut self) -> Result<&[u8], io::Error> {
96
-        self.0.fill_buf()
97
-    }
98
-
99
-    fn consume(&mut self, amt: usize) {
100
-        self.0.consume(amt)
101
-    }
102
-}
103
-
104
-/// Implement Write-Trait for Tuple-Struct W
105
-/// Simply calls `write` and `flush` from StdoutLock
106
-impl<'a> Write for W<'a> {
107
-    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
108
-        self.0.write(buf)
109
-    }
110
-
111
-    fn flush(&mut self) -> Result<(), io::Error> {
112
-        self.0.flush()
113
-    }
114
-}

+ 41
- 1
hw6/task2/src/unit_tests_shell.rs Vedi File

1
 #[cfg(test)]
1
 #[cfg(test)]
2
 mod test {
2
 mod test {
3
-    use shell::Shell;
3
+    pub use shell::Shell;
4
+    use command::Command;
5
+    use command::CommandNotFoundError;
6
+    use std::str::FromStr;
7
+    use std::ffi::OsString;
8
+
9
+    #[test]
10
+    fn test_command_empty_whitespace() {
11
+        assert_eq!(Command::from_str("       ").unwrap(), Command::Empty);
12
+    }
13
+
14
+    #[test]
15
+    fn test_command_empty_tab() {
16
+        assert_eq!(Command::from_str("\t").unwrap(), Command::Empty);
17
+    }
18
+
19
+    #[test]
20
+    fn test_command_cd() {
21
+        assert_eq!(
22
+            Command::from_str("cd /home/peter/").unwrap(),
23
+            Command::Cd(Some(OsString::from("/home/peter/")))
24
+        );
25
+    }
26
+
27
+    #[test]
28
+    fn test_command_home() {
29
+        assert_eq!(Command::from_str("cd").unwrap(), Command::Cd(None));
30
+    }
31
+
32
+    #[test]
33
+    fn test_command_exit() {
34
+        assert_eq!(Command::from_str("exit").unwrap(), Command::Exit);
35
+    }
36
+
37
+    #[test]
38
+    fn test_command_not_found() {
39
+        assert_eq!(
40
+            Command::from_str("awdeiu33we").unwrap_err(),
41
+            CommandNotFoundError
42
+        );
43
+    }
4
 
44
 
5
     #[test]
45
     #[test]
6
     fn test_prompt_in_memory_with_string() {
46
     fn test_prompt_in_memory_with_string() {

Loading…
Annulla
Salva