auth

Paddy 2015-03-24 Parent:e090a69e711f Child:3e8964a914ef

152:de5e09680f6b Go to Latest

auth/scope_test.go

Implement postgres version of scopeStore. Update the authd server to use postgres as its scopeStore, instead of memstore. panic when starting the authd server if the CreateScopes call fails. This should, ideally, ignore ErrScopeAlreadyExists errors, but does not as of this commit. Update the simple.gotmpl template to properly display scopes, after switching to the Scope type instead of simply passing around the string the client supplied broke the template and I never bothered fixing it. Update the updateScopes method on the scopeStore (and the corresponding UpdateScopes method on the Context type) to be updateScope/UpdateScope. Operating on several scopes at a time like that is simply too challenging in SQL and I can't justify the complexity with a use case. Add a helper method to ScopeChange called Empty(), which returns true if the ScopeChange is full of nil values. Remove the ID from the ScopeChange type, because we're no longer accepting multiple ScopeChange types in UpdateScope, so we can supply that information outside the ScopeChange, which matches the rest of our update* methods. Correct our tests in scope_test.go to correctly use the updateScope method instead of the old updateScopes method. This generally just resulted in calling updateScope multiple times, as opposed to just once. Add a scope table initialization to the sql/postgres_init.sql script.

History
paddy@134 1 package auth
paddy@134 2
paddy@134 3 import "testing"
paddy@134 4
paddy@134 5 var scopeStores = []scopeStore{NewMemstore()}
paddy@134 6
paddy@134 7 func compareScopes(scope1, scope2 Scope) (success bool, field string, val1, val2 interface{}) {
paddy@134 8 if scope1.ID != scope2.ID {
paddy@134 9 return false, "ID", scope1.ID, scope2.ID
paddy@134 10 }
paddy@134 11 if scope1.Name != scope2.Name {
paddy@134 12 return false, "Name", scope1.Name, scope2.Name
paddy@134 13 }
paddy@134 14 if scope1.Description != scope2.Description {
paddy@134 15 return false, "Description", scope1.Description, scope2.Description
paddy@134 16 }
paddy@134 17 return true, "", nil, nil
paddy@134 18 }
paddy@134 19
paddy@134 20 func TestScopeInScopeStore(t *testing.T) {
paddy@134 21 scope := Scope{
paddy@134 22 ID: "testscope",
paddy@134 23 Name: "Test Scope",
paddy@134 24 Description: "Access to testing data.",
paddy@134 25 }
paddy@134 26 scope2 := Scope{
paddy@134 27 ID: "testscope2",
paddy@134 28 Name: "Test Scope 2",
paddy@134 29 Description: "Access to minions.",
paddy@134 30 }
paddy@134 31 scope3 := Scope{
paddy@134 32 ID: "testscope3",
paddy@134 33 Name: "Test Scope 3",
paddy@134 34 Description: "Access to bananas.",
paddy@134 35 }
paddy@134 36 updatedName := "Updated Scope"
paddy@134 37 updatedDescription := "An updated scope."
paddy@134 38 update := ScopeChange{
paddy@134 39 Name: &updatedName,
paddy@134 40 }
paddy@134 41 update2 := ScopeChange{
paddy@134 42 Description: &updatedDescription,
paddy@134 43 }
paddy@134 44 update3 := ScopeChange{
paddy@134 45 Name: &updatedName,
paddy@134 46 Description: &updatedDescription,
paddy@134 47 }
paddy@134 48 for _, store := range scopeStores {
paddy@134 49 context := Context{scopes: store}
paddy@134 50 retrieved, err := context.GetScopes([]string{scope.ID})
paddy@134 51 if len(retrieved) != 0 {
paddy@134 52 t.Logf("%+v", retrieved)
paddy@134 53 t.Errorf("Expected %d results, got %d from %T", 0, len(retrieved), store)
paddy@134 54 }
paddy@134 55 if e, ok := err.(ErrScopeNotFound); !ok {
paddy@134 56 t.Errorf("Expected ErrScopeNotFound, got %+v instead for %T", err, store)
paddy@134 57 } else {
paddy@134 58 if e.Pos != 0 {
paddy@134 59 t.Errorf("Expected the error to be in position %d, got position %d from %T", 0, e.Pos, store)
paddy@134 60 }
paddy@134 61 if e.ID != scope.ID {
paddy@134 62 t.Errorf("Expected the error to be with scope %s, got %s from %T", scope.ID, e.ID, store)
paddy@134 63 }
paddy@134 64 }
paddy@134 65 err = context.CreateScopes([]Scope{scope})
paddy@134 66 if err != nil {
paddy@134 67 t.Errorf("Error saving scope to %T: %s", store, err)
paddy@134 68 }
paddy@134 69 err = context.CreateScopes([]Scope{scope})
paddy@134 70 if e, ok := err.(ErrScopeAlreadyExists); !ok {
paddy@134 71 t.Errorf("Expected ErrScopeAlreadyExists, got %s instead for %T", err, store)
paddy@134 72 } else {
paddy@134 73 if e.Pos != 0 {
paddy@134 74 t.Errorf("Expected the error to be in position %d, got position %d from %T", 0, e.Pos, store)
paddy@134 75 }
paddy@134 76 if e.ID != scope.ID {
paddy@134 77 t.Errorf("Expected the error to be for ID %s, got %s from %T", scope.ID, e.ID, store)
paddy@134 78 }
paddy@134 79 }
paddy@134 80 retrieved, err = context.GetScopes([]string{scope.ID})
paddy@134 81 if err != nil {
paddy@134 82 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
paddy@134 83 }
paddy@134 84 if len(retrieved) != 1 {
paddy@134 85 t.Logf("%+v", retrieved)
paddy@134 86 t.Errorf("Expected %d results, got %d from %T", 1, len(retrieved), store)
paddy@134 87 }
paddy@134 88 success, field, val1, val2 := compareScopes(scope, retrieved[0])
paddy@134 89 if !success {
paddy@134 90 t.Errorf("Expected %s to be %+v, got %+v from %T", field, val1, val2, store)
paddy@134 91 }
paddy@134 92 err = context.CreateScopes([]Scope{scope2, scope3})
paddy@134 93 if err != nil {
paddy@134 94 t.Errorf("Unexpected error trying to create scope2 and scope3 in %T: %+v", store, err)
paddy@134 95 }
paddy@134 96 retrieved, err = context.GetScopes([]string{scope.ID, scope2.ID, scope3.ID})
paddy@134 97 if err != nil {
paddy@134 98 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
paddy@134 99 }
paddy@134 100 if len(retrieved) != 3 {
paddy@134 101 t.Logf("%+v", retrieved)
paddy@134 102 t.Errorf("Expected %d results, got %d from %T", 3, len(retrieved), store)
paddy@134 103 }
paddy@134 104 for pos, s := range []Scope{scope, scope2, scope3} {
paddy@134 105 success, field, val1, val2 = compareScopes(s, retrieved[pos])
paddy@134 106 if !success {
paddy@134 107 t.Errorf("Expected %s to be %+v for scope %s, got %+v from %T", field, val1, s.ID, val2, store)
paddy@134 108 }
paddy@134 109 }
paddy@152 110 err = context.UpdateScope(scope.ID, update)
paddy@134 111 if err != nil {
paddy@152 112 t.Errorf("Unexpected error updating scope in %T: %+v", store, err)
paddy@134 113 }
paddy@134 114 scope.ApplyChange(update)
paddy@152 115 err = context.UpdateScope(scope2.ID, update2)
paddy@152 116 if err != nil {
paddy@152 117 t.Errorf("Unexpected error updating scope in %T: %+v", store, err)
paddy@152 118 }
paddy@134 119 scope2.ApplyChange(update2)
paddy@152 120 err = context.UpdateScope(scope3.ID, update3)
paddy@152 121 if err != nil {
paddy@152 122 t.Errorf("Unexpected error updating scope in %T: %+v", store, err)
paddy@152 123 }
paddy@134 124 scope3.ApplyChange(update3)
paddy@134 125 retrieved, err = context.ListScopes()
paddy@134 126 if err != nil {
paddy@134 127 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
paddy@134 128 }
paddy@134 129 if len(retrieved) != 3 {
paddy@134 130 t.Logf("%+v", retrieved)
paddy@134 131 t.Errorf("Expected %d results, got %d from %T", 3, len(retrieved), store)
paddy@134 132 }
paddy@134 133 for pos, s := range []Scope{scope, scope2, scope3} {
paddy@134 134 success, field, val1, val2 = compareScopes(s, retrieved[pos])
paddy@134 135 if !success {
paddy@136 136 t.Errorf("Expected %s to be %+v for scope %s, got %+v from %T", field, val1, s.ID, val2, store)
paddy@134 137 }
paddy@134 138 }
paddy@134 139 err = context.RemoveScopes([]string{scope.ID, scope2.ID, scope3.ID})
paddy@134 140 if err != nil {
paddy@134 141 t.Errorf("Unexpected error removing scopes from %T: %+v", store, err)
paddy@134 142 }
paddy@134 143 retrieved, err = context.ListScopes()
paddy@134 144 if err != nil {
paddy@134 145 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
paddy@134 146 }
paddy@134 147 if len(retrieved) != 0 {
paddy@134 148 t.Logf("%+v", retrieved)
paddy@134 149 t.Errorf("Expected %d results, got %d from %T", 0, len(retrieved), store)
paddy@134 150 }
paddy@134 151 err = context.RemoveScopes([]string{scope.ID})
paddy@134 152 if err == nil {
paddy@134 153 t.Errorf("No error returned removing non-existent scopes from %T", store)
paddy@134 154 }
paddy@134 155 if e, ok := err.(ErrScopeNotFound); !ok {
paddy@134 156 t.Errorf("Unexpected error removing non-existent scopes from %T: %+v", store, err)
paddy@134 157 } else {
paddy@134 158 if e.Pos != 0 {
paddy@134 159 t.Errorf("Expected error to be for scope ID in pos %d, but got %d from %T", 0, e.Pos, store)
paddy@134 160 }
paddy@134 161 if e.ID != scope.ID {
paddy@134 162 t.Errorf("Expected error to be for scope ID %s, but got %s from %T", scope.ID, e.ID, store)
paddy@134 163 }
paddy@134 164 }
paddy@152 165 err = context.UpdateScope(scope.ID, update)
paddy@134 166 if err == nil {
paddy@134 167 t.Errorf("No error returned updating non-existent scopes from %T", store)
paddy@134 168 }
paddy@134 169 if e, ok := err.(ErrScopeNotFound); !ok {
paddy@134 170 t.Errorf("Unexpected error updating non-existent scopes from %T: %+v", store, err)
paddy@134 171 } else {
paddy@134 172 if e.Pos != 0 {
paddy@134 173 t.Errorf("Expected error to be for scope ID in pos %d, but got %d from %T", 0, e.Pos, store)
paddy@134 174 }
paddy@134 175 if e.ID != scope.ID {
paddy@134 176 t.Errorf("Expected error to be for scope ID %s, but got %s from %T", scope.ID, e.ID, store)
paddy@134 177 }
paddy@134 178 }
paddy@134 179 }
paddy@134 180 }
paddy@134 181
paddy@134 182 func TestScopeErrors(t *testing.T) {
paddy@134 183 errors := map[string]error{
paddy@134 184 "scope test couldn't be found": ErrScopeNotFound{ID: "test", Pos: 0},
paddy@134 185 "scope test already exists": ErrScopeAlreadyExists{ID: "test", Pos: 0},
paddy@134 186 }
paddy@134 187 for expectation, e := range errors {
paddy@134 188 if e.Error() != expectation {
paddy@134 189 t.Errorf("Expected %+v to produce '%s', produced '%s'", e, expectation, e.Error())
paddy@134 190 }
paddy@134 191 }
paddy@134 192 }