github.com/wostzone/hub/auth@v0.0.0-20220118060317-7bb375743b17/pkg/unpwstore/PasswordFileStore_test.go (about) 1 package unpwstore_test 2 3 import ( 4 "fmt" 5 "os" 6 "path" 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/sirupsen/logrus" 12 "github.com/stretchr/testify/assert" 13 "github.com/wostzone/hub/auth/pkg/unpwstore" 14 "github.com/wostzone/hub/lib/client/pkg/config" 15 ) 16 17 const unpwFileName = "testunpwstore.passwd" 18 19 var unpwFilePath string 20 21 var configFolder string 22 23 // TestMain for all auth tests, setup of default folders and filenames 24 func TestMain(m *testing.M) { 25 config.SetLogging("info", "") 26 cwd, _ := os.Getwd() 27 homeFolder := path.Join(cwd, "../../test") 28 configFolder = path.Join(homeFolder, "config") 29 30 // Make sure ACL and password files exist 31 unpwFilePath = path.Join(configFolder, unpwFileName) 32 fp, _ := os.Create(unpwFilePath) 33 fp.Close() 34 35 res := m.Run() 36 os.Exit(res) 37 } 38 39 func TestOpenClosePWFile(t *testing.T) { 40 fp, _ := os.Create(unpwFilePath) 41 fp.Close() 42 unpwStore := unpwstore.NewPasswordFileStore(unpwFilePath, "TestOpenClosePWFile") 43 err := unpwStore.Open() 44 assert.NoError(t, err) 45 time.Sleep(time.Second * 1) 46 assert.NoError(t, err) 47 unpwStore.Close() 48 } 49 50 func TestSetPasswordTwoStores(t *testing.T) { 51 const user1 = "user1" 52 const user2 = "user2" 53 const hash1 = "hash1" 54 const hash2 = "hash2" 55 fp, _ := os.Create(unpwFilePath) 56 fp.Close() 57 // create 2 separate stores 58 pwStore1 := unpwstore.NewPasswordFileStore(unpwFilePath, "TestSetPasswordTwoStores-store1") 59 err := pwStore1.Open() 60 assert.NoError(t, err) 61 pwStore2 := unpwstore.NewPasswordFileStore(unpwFilePath, "TestSetPasswordTwoStores-Store2") 62 err = pwStore2.Open() 63 assert.NoError(t, err) 64 65 // set hash in store 1, should appear in store 2 66 err = pwStore1.SetPasswordHash(user1, hash1) 67 assert.NoError(t, err) 68 // wait for reload 69 time.Sleep(time.Second * 1) 70 // check mode of pw file 71 info, err := os.Stat(unpwFilePath) 72 assert.NoError(t, err) 73 mode := info.Mode() 74 assert.Equal(t, 0600, int(mode), "file mode not 0600") 75 76 // read back 77 // force reload. Don't want to wait 78 pwStore2.Reload() 79 hash := pwStore2.GetPasswordHash(user1) 80 assert.Equal(t, hash1, hash) 81 82 // do it again but in reverse 83 logrus.Infof("- do it again in reverse -") 84 err = pwStore2.SetPasswordHash(user2, hash2) 85 assert.NoError(t, err) 86 time.Sleep(time.Second * 2) 87 hash = pwStore1.GetPasswordHash(user2) 88 assert.Equal(t, hash2, hash) 89 // time.Sleep(time.Second * 1) 90 91 assert.NoError(t, err) 92 time.Sleep(time.Second * 1) 93 pwStore1.Close() 94 pwStore2.Close() 95 } 96 97 func TestNoPasswordFile(t *testing.T) { 98 pwFile := path.Join(configFolder, "missingpasswordfile") 99 pwStore := unpwstore.NewPasswordFileStore(pwFile, "TestNoPasswordFile") 100 err := pwStore.Open() 101 assert.Error(t, err) 102 103 pwStore.Close() 104 } 105 106 // Load test if one writer with second reader 107 func TestConcurrentReadWrite(t *testing.T) { 108 var wg sync.WaitGroup 109 var i int 110 111 // start with empty file 112 fp, _ := os.Create(unpwFilePath) 113 fp.Close() 114 115 // two stores in parallel 116 pwStore1 := unpwstore.NewPasswordFileStore(unpwFilePath, "TestConcurrentReadWrite-store1 (writer)") 117 err := pwStore1.Open() 118 assert.NoError(t, err) 119 pwStore2 := unpwstore.NewPasswordFileStore(unpwFilePath, "TestConcurrentReadWrite-store2 (reader)") 120 err = pwStore2.Open() 121 assert.NoError(t, err) 122 123 wg.Add(1) 124 go func() { 125 for i = 0; i < 30; i++ { 126 thingID := fmt.Sprintf("thing-%d", i) 127 err2 := pwStore1.SetPasswordHash(thingID, "hash1") 128 time.Sleep(time.Millisecond * 1) 129 if err2 != nil { 130 assert.NoError(t, err2) 131 } 132 } 133 wg.Done() 134 }() 135 wg.Wait() 136 // time to catch up the file watcher debouncing 137 time.Sleep(time.Second * 2) 138 139 // both stores should be fully up to date 140 assert.Equal(t, i, pwStore1.Count()) 141 assert.Equal(t, i, pwStore2.Count()) 142 143 // 144 pwStore1.Close() 145 pwStore2.Close() 146 } 147 148 func TestWritePwToTempFail(t *testing.T) { 149 pws := make(map[string]string) 150 pwStore1 := unpwstore.NewPasswordFileStore(unpwFilePath, "TestWritePwToTempFail") 151 err := pwStore1.Open() 152 assert.NoError(t, err) 153 _, err = unpwstore.WritePasswordsToTempFile("/badfolder", pws) 154 assert.Error(t, err) 155 pwStore1.Close() 156 }