git.fiddlerwoaroof.com
Browse code

isolates user creation

Greg Wiley authored on 11/04/2017 23:53:58
Showing 3 changed files
... ...
@@ -39,7 +39,7 @@ t_%.o: %.cc
39 39
 #token_test: token_test.o t_token.o
40 40
 #	$(CXX) $(CXXFLAGS) $(CPPFLAGS)  -lpam -o $@ $^
41 41
 
42
-user_test: user_test.o user.o
42
+user_test: user_test.o t_user.o
43 43
 	$(CXX) $(CXXFLAGS) $(CPPFLAGS)  -o $@ $^
44 44
 
45 45
 
... ...
@@ -1,9 +1,11 @@
1
-#include "user.h"
2
-
1
+#include <memory>
3 2
 #include <vector>
4 3
 #include <string>
5 4
 #include <pwd.h>
6 5
 #include <unistd.h>
6
+#include <iostream>
7
+
8
+#include "user.h"
7 9
 #include "test_support.h"
8 10
 
9 11
 user::user(struct passwd *sys_info) : info(sys_info) {
... ...
@@ -19,7 +21,7 @@ class concrete_user : public user {
19 21
      private:
20 22
         std::vector<char> buffer_;
21 23
         std::shared_ptr<struct passwd> store_;
22
-    public:
24
+     public:
23 25
          concrete_user(const std::vector<char> &buffer, const std::shared_ptr<struct passwd> &store);
24 26
 };
25 27
 
... ...
@@ -31,12 +33,16 @@ concrete_user::concrete_user(const std::vector<char> &buffer, const std::shared_
31 33
 
32 34
 const std::shared_ptr<user> create_user(const std::string &user_name) {
33 35
     std::vector<char> buffer(sysconf(_SC_GETPW_R_SIZE_MAX));
34
-    std::shared_ptr<struct passwd> sys_passwd;
36
+    std::shared_ptr<struct passwd> sys_passwd(new struct passwd);
35 37
     struct passwd *found_passwd(0);
36 38
 
37 39
     getpwnam_r(user_name.c_str(), sys_passwd.get(), buffer.data(), buffer.size(), &found_passwd);
38 40
 
39
-    return std::shared_ptr<user>(new concrete_user(buffer, sys_passwd));
41
+    std::shared_ptr<user> rval;
42
+    if (found_passwd) {
43
+        rval.reset(new concrete_user(buffer, sys_passwd));
44
+    }
45
+    return rval;
40 46
 }
41 47
 
42 48
 
... ...
@@ -1,8 +1,10 @@
1 1
 #include <memory>
2
-
2
+#include <iostream>
3 3
 #include "user.h"
4 4
 #include "test_util.h"
5
-int gets_home_directory() {
5
+
6
+
7
+bool gets_home_directory() {
6 8
     //given
7 9
     const char *expected_home_directory = "home/msmith";
8 10
     struct passwd test_passwd;
... ...
@@ -17,18 +19,23 @@ int gets_home_directory() {
17 19
     return expected_home_directory == actual_home_directory;
18 20
 }
19 21
 
20
-std::string fake_home_directory("");
22
+
23
+std::shared_ptr<struct passwd> fake_passwd;
21 24
 int fake_getpwnam_r(const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result) {
22
-  pwd->pw_dir = const_cast<char *>(fake_home_directory.c_str());
23
-  result = &pwd;
24
-  return 0;
25
+  if (fake_passwd) {
26
+      *pwd = *fake_passwd;
27
+      *result = pwd;
28
+      return 0;
29
+  }
30
+  return -1;
25 31
 }
26 32
 
27
-int initialize_concrete_user() {
33
+bool create_user_succeeds() {
28 34
     // given
29 35
     std::string username("msmith");
30 36
     std::string home_directory("this is my home");
31
-    fake_home_directory = home_directory;
37
+    fake_passwd.reset(new struct passwd);
38
+    fake_passwd->pw_dir = const_cast<char *>(home_directory.c_str());
32 39
 
33 40
     // when
34 41
     std::shared_ptr<user> user(create_user(username));
... ...
@@ -41,11 +48,27 @@ int initialize_concrete_user() {
41 48
 
42 49
 }
43 50
 
51
+bool create_user_nonexistent() {
52
+    // given
53
+    std::string username("msmith");
54
+
55
+    // when
56
+    std::shared_ptr<user> user(create_user(username));
57
+
58
+    // then
59
+    check(!user, "no user should be returned");
60
+
61
+    succeed();
62
+}
63
+
44 64
 RESET_VARS_START
65
+fake_passwd.reset((struct passwd *)0);
45 66
 RESET_VARS_END
46 67
 
47 68
 int run_tests() {
48 69
     test(gets_home_directory);
70
+    test(create_user_succeeds);
71
+    test(create_user_nonexistent);
49 72
     succeed();
50 73
 }
51 74
 int main(int argc, char *argv[]) {