]> ruderich.org/simon Gitweb - nsscash/nsscash.git/blobdiff - main_test.go
.github: update upstream actions to latest version
[nsscash/nsscash.git] / main_test.go
index 181930f29da7034c7bac6d94b16b09ea7f11cd7d..b5fc2ea92c57068ba9dc6016d39dfaa8af7b328c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019  Simon Ruderich
+// Copyright (C) 2019-2021  Simon Ruderich
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU Affero General Public License as published by
@@ -25,6 +25,7 @@ import (
        "net/http"
        "net/http/httptest"
        "os"
+       "path/filepath"
        "reflect"
        "runtime"
        "strings"
@@ -34,7 +35,7 @@ import (
 
 const (
        configPath  = "testdata/config.toml"
-       statePath   = "testdata/state.json"
+       statePath   = "testdata/var/state.json"
        passwdPath  = "testdata/passwd.nsscash"
        plainPath   = "testdata/plain"
        groupPath   = "testdata/group.nsscash"
@@ -155,8 +156,8 @@ func mustMakeOld(t *testing.T, paths ...string) {
        }
 }
 
-// mustMakeOld verifies that all paths have a modification time in the past,
-// as set by mustMakeOld().
+// mustBeOld verifies that all paths have a modification time in the past, as
+// set by mustMakeOld.
 func mustBeOld(t *testing.T, paths ...string) {
        for _, p := range paths {
                i, err := os.Stat(p)
@@ -165,8 +166,7 @@ func mustBeOld(t *testing.T, paths ...string) {
                }
 
                mtime := i.ModTime()
-               now := time.Now()
-               if now.Sub(mtime) < time.Hour {
+               if time.Since(mtime) < time.Hour {
                        t.Errorf("%q was recently modified", p)
                }
        }
@@ -181,8 +181,7 @@ func mustBeNew(t *testing.T, paths ...string) {
                }
 
                mtime := i.ModTime()
-               now := time.Now()
-               if now.Sub(mtime) > time.Hour {
+               if time.Since(mtime) > time.Hour {
                        t.Errorf("%q was not recently modified", p)
                }
        }
@@ -197,6 +196,7 @@ func TestMainFetch(t *testing.T) {
                // Perform most tests with passwd for simplicity
                fetchPasswdCacheFileDoesNotExist,
                fetchPasswd404,
+               fetchPasswdUnexpected304,
                fetchPasswdEmpty,
                fetchPasswdInvalid,
                fetchPasswdLimits,
@@ -216,6 +216,7 @@ func TestMainFetch(t *testing.T) {
                fetchCannotDeploy,
                fetchSecondFetchFails,
                fetchBasicAuth,
+               // TODO: fetchCannotDeployMultiple,
        }
 
        // HTTP tests
@@ -269,6 +270,13 @@ func runMainTest(t *testing.T, f func(args), tls *tls.Config) {
                        // Remove the file at the end of this test run, if it
                        // was created
                        defer os.Remove(p)
+
+                       dir := filepath.Dir(p)
+                       err = os.MkdirAll(dir, 0755)
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+                       defer os.Remove(dir) // remove empty directories
                }
 
                var handler func(http.ResponseWriter, *http.Request)
@@ -318,7 +326,25 @@ func fetchPasswd404(a args) {
                "status code 404")
 
        mustNotExist(t, statePath, plainPath, groupPath)
-       mustBeOld(a.t, passwdPath)
+       mustBeOld(t, passwdPath)
+}
+
+func fetchPasswdUnexpected304(a args) {
+       t := a.t
+       mustWritePasswdConfig(t, a.url)
+       mustCreate(t, passwdPath)
+
+       *a.handler = func(w http.ResponseWriter, r *http.Request) {
+               // 304
+               w.WriteHeader(http.StatusNotModified)
+       }
+
+       err := mainFetch(configPath)
+       mustBeErrorWithSubstring(t, err,
+               "status code 304 but did not send If-Modified-Since")
+
+       mustNotExist(t, statePath, plainPath, groupPath)
+       mustBeOld(t, passwdPath)
 }
 
 func fetchPasswdEmpty(a args) {
@@ -688,6 +714,7 @@ func fetchStateCannotRead(a args) {
                statePath+": permission denied")
 
        mustNotExist(t, passwdPath, plainPath, groupPath)
+       mustBeOld(t, statePath)
 }
 
 func fetchStateInvalid(a args) {
@@ -710,23 +737,27 @@ func fetchStateCannotWrite(a args) {
        mustHaveHash(t, groupPath, "da39a3ee5e6b4b0d3255bfef95601890afd80709")
 
        *a.handler = func(w http.ResponseWriter, r *http.Request) {
-               // To prevent mainFetch() from trying to update groupPath
-               // which will also fail
-               w.WriteHeader(http.StatusNotModified)
+               if r.URL.Path != "/group" {
+                       return
+               }
+
+               fmt.Fprintln(w, "root:x:0:")
+               fmt.Fprintln(w, "daemon:x:1:andariel,duriel,mephisto,diablo,baal")
        }
 
-       err := os.Chmod("testdata", 0500)
+       err := os.Chmod(filepath.Dir(statePath), 0500)
        if err != nil {
                t.Fatal(err)
        }
-       defer os.Chmod("testdata", 0755)
+       defer os.Chmod(filepath.Dir(statePath), 0755)
 
        err = mainFetch(configPath)
        mustBeErrorWithSubstring(t, err,
                "permission denied")
 
        mustNotExist(t, statePath, passwdPath, plainPath)
-       mustBeOld(t, groupPath)
+       mustBeNew(t, groupPath)
+       mustHaveHash(t, groupPath, "8c27a8403278ba2e392b86d98d4dff1fdefcafdd")
 }
 
 func fetchCannotDeploy(a args) {
@@ -858,7 +889,7 @@ password = "%[6]s"
        err = mainFetch(configPath)
        mustBeErrorWithSubstring(t, err,
                "file[0].username/passsword in use and unsafe permissions "+
-                       "-rw-r--r-- on \"testdata/config.toml\"")
+                       "-rw-r--r-- on \""+configPath+"\"")
 
        mustNotExist(t, statePath, groupPath, plainPath)
        mustBeOld(t, passwdPath)
@@ -936,3 +967,52 @@ ca = "%[4]s"
        mustNotExist(t, statePath, plainPath, groupPath)
        mustBeOld(t, passwdPath)
 }
+
+/*
+TODO: implement code for this test
+
+func fetchCannotDeployMultiple(a args) {
+       t := a.t
+       newPlainDir := "testdata/x"
+       newPlainPath := newPlainDir + "/plain"
+       mustWriteConfig(t, fmt.Sprintf(`
+statepath = "%[1]s"
+
+[[file]]
+type = "group"
+url = "%[2]s/group"
+path = "%[3]s"
+
+[[file]]
+type = "plain"
+url = "%[2]s/plain"
+path = "%[4]s"
+`, statePath, a.url, groupPath, newPlainPath))
+       os.Mkdir(newPlainDir, 0755)
+       defer os.RemoveAll(newPlainDir)
+       mustCreate(t, groupPath)
+       mustCreate(t, newPlainPath)
+       mustHaveHash(t, groupPath, "da39a3ee5e6b4b0d3255bfef95601890afd80709")
+
+       *a.handler = func(w http.ResponseWriter, r *http.Request) {
+               if r.URL.Path == "/group" {
+                       fmt.Fprintln(w, "root:x:0:")
+               }
+               if r.URL.Path == "/plain" {
+                       fmt.Fprintln(w, "some file")
+               }
+       }
+
+       err := os.Chmod(newPlainDir, 0500)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       err = mainFetch(configPath)
+       mustBeErrorWithSubstring(t, err,
+               "permission denied")
+
+       mustNotExist(t, statePath, passwdPath, plainPath)
+       mustBeOld(t, groupPath, newPlainPath)
+}
+*/