]>
Commit | Line | Data |
---|---|---|
041b39d2 | 1 | use std::env::*; |
60c5eb7d | 2 | use std::ffi::{OsStr, OsString}; |
041b39d2 | 3 | |
9c376795 | 4 | use rand::distributions::{Alphanumeric, DistString}; |
041b39d2 | 5 | |
9ffffee4 FG |
6 | mod common; |
7 | use common::test_rng; | |
781aab86 | 8 | use std::thread; |
9c376795 FG |
9 | |
10 | #[track_caller] | |
041b39d2 | 11 | fn make_rand_name() -> OsString { |
9c376795 | 12 | let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10)); |
041b39d2 XL |
13 | let n = OsString::from(n); |
14 | assert!(var_os(&n).is_none()); | |
15 | n | |
16 | } | |
17 | ||
18 | fn eq(a: Option<OsString>, b: Option<&str>) { | |
19 | assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s)); | |
20 | } | |
21 | ||
22 | #[test] | |
23 | fn test_set_var() { | |
24 | let n = make_rand_name(); | |
25 | set_var(&n, "VALUE"); | |
26 | eq(var_os(&n), Some("VALUE")); | |
27 | } | |
28 | ||
29 | #[test] | |
30 | fn test_remove_var() { | |
31 | let n = make_rand_name(); | |
32 | set_var(&n, "VALUE"); | |
33 | remove_var(&n); | |
34 | eq(var_os(&n), None); | |
35 | } | |
36 | ||
37 | #[test] | |
38 | fn test_set_var_overwrite() { | |
39 | let n = make_rand_name(); | |
40 | set_var(&n, "1"); | |
41 | set_var(&n, "2"); | |
42 | eq(var_os(&n), Some("2")); | |
43 | set_var(&n, ""); | |
44 | eq(var_os(&n), Some("")); | |
45 | } | |
46 | ||
47 | #[test] | |
48 | #[cfg_attr(target_os = "emscripten", ignore)] | |
49 | fn test_var_big() { | |
50 | let mut s = "".to_string(); | |
51 | let mut i = 0; | |
52 | while i < 100 { | |
53 | s.push_str("aaaaaaaaaa"); | |
54 | i += 1; | |
55 | } | |
56 | let n = make_rand_name(); | |
57 | set_var(&n, &s); | |
58 | eq(var_os(&n), Some(&s)); | |
59 | } | |
60 | ||
61 | #[test] | |
62 | #[cfg_attr(target_os = "emscripten", ignore)] | |
63 | fn test_env_set_get_huge() { | |
64 | let n = make_rand_name(); | |
8faf50e0 | 65 | let s = "x".repeat(10000); |
041b39d2 XL |
66 | set_var(&n, &s); |
67 | eq(var_os(&n), Some(&s)); | |
68 | remove_var(&n); | |
69 | eq(var_os(&n), None); | |
70 | } | |
71 | ||
72 | #[test] | |
73 | fn test_env_set_var() { | |
74 | let n = make_rand_name(); | |
75 | ||
76 | let mut e = vars_os(); | |
77 | set_var(&n, "VALUE"); | |
60c5eb7d | 78 | assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" })); |
041b39d2 | 79 | |
60c5eb7d | 80 | assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" })); |
041b39d2 | 81 | } |
fc512014 XL |
82 | |
83 | #[test] | |
84 | #[cfg_attr(not(any(unix, windows)), ignore, allow(unused))] | |
85 | #[allow(deprecated)] | |
86 | fn env_home_dir() { | |
87 | use std::path::PathBuf; | |
88 | ||
89 | fn var_to_os_string(var: Result<String, VarError>) -> Option<OsString> { | |
90 | match var { | |
91 | Ok(var) => Some(OsString::from(var)), | |
92 | Err(VarError::NotUnicode(var)) => Some(var), | |
93 | _ => None, | |
94 | } | |
95 | } | |
96 | ||
97 | cfg_if::cfg_if! { | |
98 | if #[cfg(unix)] { | |
99 | let oldhome = var_to_os_string(var("HOME")); | |
100 | ||
101 | set_var("HOME", "/home/MountainView"); | |
102 | assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); | |
103 | ||
104 | remove_var("HOME"); | |
105 | if cfg!(target_os = "android") { | |
106 | assert!(home_dir().is_none()); | |
107 | } else { | |
108 | // When HOME is not set, some platforms return `None`, | |
109 | // but others return `Some` with a default. | |
110 | // Just check that it is not "/home/MountainView". | |
111 | assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView"))); | |
112 | } | |
113 | ||
114 | if let Some(oldhome) = oldhome { set_var("HOME", oldhome); } | |
115 | } else if #[cfg(windows)] { | |
116 | let oldhome = var_to_os_string(var("HOME")); | |
117 | let olduserprofile = var_to_os_string(var("USERPROFILE")); | |
118 | ||
119 | remove_var("HOME"); | |
120 | remove_var("USERPROFILE"); | |
121 | ||
122 | assert!(home_dir().is_some()); | |
123 | ||
124 | set_var("HOME", "/home/MountainView"); | |
125 | assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); | |
126 | ||
127 | remove_var("HOME"); | |
128 | ||
129 | set_var("USERPROFILE", "/home/MountainView"); | |
130 | assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); | |
131 | ||
132 | set_var("HOME", "/home/MountainView"); | |
133 | set_var("USERPROFILE", "/home/PaloAlto"); | |
134 | assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); | |
135 | ||
136 | remove_var("HOME"); | |
137 | remove_var("USERPROFILE"); | |
138 | ||
139 | if let Some(oldhome) = oldhome { set_var("HOME", oldhome); } | |
140 | if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); } | |
141 | } | |
142 | } | |
143 | } | |
781aab86 FG |
144 | |
145 | #[test] // miri shouldn't detect any data race in this fn | |
146 | #[cfg_attr(any(not(miri), target_os = "emscripten"), ignore)] | |
147 | fn test_env_get_set_multithreaded() { | |
148 | let getter = thread::spawn(|| { | |
149 | for _ in 0..100 { | |
150 | let _ = var_os("foo"); | |
151 | } | |
152 | }); | |
153 | ||
154 | let setter = thread::spawn(|| { | |
155 | for _ in 0..100 { | |
156 | set_var("foo", "bar"); | |
157 | } | |
158 | }); | |
159 | ||
160 | let _ = getter.join(); | |
161 | let _ = setter.join(); | |
162 | } |