| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package coordinatorTest | 5 package coordinatorTest |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "fmt" | 8 "fmt" |
| 9 "strings" |
| 9 | 10 |
| 10 "github.com/golang/protobuf/proto" | 11 "github.com/golang/protobuf/proto" |
| 11 ds "github.com/luci/gae/service/datastore" | 12 ds "github.com/luci/gae/service/datastore" |
| 13 "github.com/luci/gae/service/info" |
| 12 "github.com/luci/luci-go/appengine/logdog/coordinator" | 14 "github.com/luci/luci-go/appengine/logdog/coordinator" |
| 13 "github.com/luci/luci-go/appengine/logdog/coordinator/config" | 15 "github.com/luci/luci-go/appengine/logdog/coordinator/config" |
| 14 "github.com/luci/luci-go/appengine/tumble" | 16 "github.com/luci/luci-go/appengine/tumble" |
| 15 "github.com/luci/luci-go/common/clock" | 17 "github.com/luci/luci-go/common/clock" |
| 16 "github.com/luci/luci-go/common/clock/testclock" | 18 "github.com/luci/luci-go/common/clock/testclock" |
| 17 luciConfig "github.com/luci/luci-go/common/config" | 19 luciConfig "github.com/luci/luci-go/common/config" |
| 18 "github.com/luci/luci-go/common/config/impl/memory" | 20 "github.com/luci/luci-go/common/config/impl/memory" |
| 19 "github.com/luci/luci-go/common/gcloud/gs" | 21 "github.com/luci/luci-go/common/gcloud/gs" |
| 20 "github.com/luci/luci-go/common/logging" | 22 "github.com/luci/luci-go/common/logging" |
| 21 "github.com/luci/luci-go/common/logging/gologger" | 23 "github.com/luci/luci-go/common/logging/gologger" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 // default) into Services. | 61 // default) into Services. |
| 60 ArchivalPublisher ArchivalPublisher | 62 ArchivalPublisher ArchivalPublisher |
| 61 } | 63 } |
| 62 | 64 |
| 63 // JoinGroup adds the named group the to the list of groups for the current | 65 // JoinGroup adds the named group the to the list of groups for the current |
| 64 // identity. | 66 // identity. |
| 65 func (e *Environment) JoinGroup(g string) { | 67 func (e *Environment) JoinGroup(g string) { |
| 66 e.AuthState.IdentityGroups = append(e.AuthState.IdentityGroups, g) | 68 e.AuthState.IdentityGroups = append(e.AuthState.IdentityGroups, g) |
| 67 } | 69 } |
| 68 | 70 |
| 71 // LeaveAllGroups clears all auth groups that the user is currently a member of. |
| 72 func (e *Environment) LeaveAllGroups() { |
| 73 e.AuthState.IdentityGroups = nil |
| 74 e.JoinGroup("all") |
| 75 } |
| 76 |
| 69 // ClearCoordinatorConfig removes the Coordinator configuration entry, | 77 // ClearCoordinatorConfig removes the Coordinator configuration entry, |
| 70 // simulating a missing config. | 78 // simulating a missing config. |
| 71 func (e *Environment) ClearCoordinatorConfig(c context.Context) { | 79 func (e *Environment) ClearCoordinatorConfig(c context.Context) { |
| 72 configSet, _ := config.ServiceConfigPath(c) | 80 configSet, _ := config.ServiceConfigPath(c) |
| 73 delete(e.Config, configSet) | 81 delete(e.Config, configSet) |
| 74 } | 82 } |
| 75 | 83 |
| 76 // ModServiceConfig loads the current service configuration, invokes the | 84 // ModServiceConfig loads the current service configuration, invokes the |
| 77 // callback with its contents, and writes the result back to config. | 85 // callback with its contents, and writes the result back to config. |
| 78 func (e *Environment) ModServiceConfig(c context.Context, fn func(*svcconfig.Coo
rdinator)) { | 86 func (e *Environment) ModServiceConfig(c context.Context, fn func(*svcconfig.Con
fig)) { |
| 79 configSet, configPath := config.ServiceConfigPath(c) | 87 configSet, configPath := config.ServiceConfigPath(c) |
| 80 | 88 |
| 81 var cfg svcconfig.Config | 89 var cfg svcconfig.Config |
| 82 e.modTextProtobuf(configSet, configPath, &cfg, func() { | 90 e.modTextProtobuf(configSet, configPath, &cfg, func() { |
| 83 » » if cfg.Coordinator == nil { | 91 » » fn(&cfg) |
| 84 » » » cfg.Coordinator = &svcconfig.Coordinator{} | |
| 85 » » } | |
| 86 » » fn(cfg.Coordinator) | |
| 87 }) | 92 }) |
| 88 } | 93 } |
| 89 | 94 |
| 90 // ModProjectConfig loads the current configuration for the named project, | 95 // ModProjectConfig loads the current configuration for the named project, |
| 91 // invokes the callback with its contents, and writes the result back to config. | 96 // invokes the callback with its contents, and writes the result back to config. |
| 92 func (e *Environment) ModProjectConfig(proj luciConfig.ProjectName, fn func(*svc
config.ProjectConfig)) { | 97 func (e *Environment) ModProjectConfig(proj luciConfig.ProjectName, fn func(*svc
config.ProjectConfig)) { |
| 93 configSet, configPath := config.ProjectConfigPath(proj) | 98 configSet, configPath := config.ProjectConfigPath(proj) |
| 94 | 99 |
| 95 var pcfg svcconfig.ProjectConfig | 100 var pcfg svcconfig.ProjectConfig |
| 96 e.modTextProtobuf(configSet, configPath, &pcfg, func() { | 101 e.modTextProtobuf(configSet, configPath, &pcfg, func() { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 e.Clock = clock.Get(c).(testclock.TestClock) | 194 e.Clock = clock.Get(c).(testclock.TestClock) |
| 190 | 195 |
| 191 // Install GAE config service settings. | 196 // Install GAE config service settings. |
| 192 c = settings.Use(c, settings.New(&settings.MemoryStorage{})) | 197 c = settings.Use(c, settings.New(&settings.MemoryStorage{})) |
| 193 | 198 |
| 194 // Setup luci-config configuration. | 199 // Setup luci-config configuration. |
| 195 c = memory.Use(c, e.Config) | 200 c = memory.Use(c, e.Config) |
| 196 e.ConfigIface = luciConfig.Get(c) | 201 e.ConfigIface = luciConfig.Get(c) |
| 197 | 202 |
| 198 // luci-config: Projects. | 203 // luci-config: Projects. |
| 204 projectName := info.Get(c).AppID() |
| 199 addProjectConfig := func(proj luciConfig.ProjectName, access ...string)
{ | 205 addProjectConfig := func(proj luciConfig.ProjectName, access ...string)
{ |
| 200 e.ModProjectConfig(proj, func(pcfg *svcconfig.ProjectConfig) { | 206 e.ModProjectConfig(proj, func(pcfg *svcconfig.ProjectConfig) { |
| 201 » » » pcfg.ReaderAuthGroups = access | 207 » » » for _, a := range access { |
| 208 » » » » parts := strings.SplitN(a, ":", 2) |
| 209 » » » » group, field := parts[0], &pcfg.ReaderAuthGroups |
| 210 » » » » if len(parts) == 2 { |
| 211 » » » » » switch parts[1] { |
| 212 » » » » » case "R": |
| 213 » » » » » » break |
| 214 » » » » » case "W": |
| 215 » » » » » » field = &pcfg.WriterAuthGroups |
| 216 » » » » » default: |
| 217 » » » » » » panic(a) |
| 218 » » » » » } |
| 219 » » » » } |
| 220 » » » » *field = append(*field, group) |
| 221 » » » } |
| 202 }) | 222 }) |
| 203 } | 223 } |
| 204 » addProjectConfig("proj-foo", "all") | 224 » addProjectConfig("proj-foo", "all:R", "all:W") |
| 205 » addProjectConfig("proj-bar", "all") | 225 » addProjectConfig("proj-bar", "all:R", "auth:W") |
| 206 » addProjectConfig("proj-exclusive", "auth") | 226 » addProjectConfig("proj-exclusive", "auth:R", "auth:W") |
| 207 | 227 |
| 208 // Add a project without a LogDog project config. | 228 // Add a project without a LogDog project config. |
| 209 e.addConfigEntry("projects/proj-unconfigured", "not-logdog.cfg", "junk") | 229 e.addConfigEntry("projects/proj-unconfigured", "not-logdog.cfg", "junk") |
| 210 e.addConfigEntry("projects/proj-malformed", svcconfig.ProjectConfigFilen
ame, "!!! not a text protobuf !!!") | 230 e.addConfigEntry("projects/proj-malformed", svcconfig.ProjectConfigFilen
ame, "!!! not a text protobuf !!!") |
| 211 | 231 |
| 212 // luci-config: Coordinator Defaults | 232 // luci-config: Coordinator Defaults |
| 213 » e.ModServiceConfig(c, func(cfg *svcconfig.Coordinator) { | 233 » e.ModServiceConfig(c, func(cfg *svcconfig.Config) { |
| 214 » » *cfg = svcconfig.Coordinator{ | 234 » » cfg.Transport = &svcconfig.Transport{ |
| 235 » » » Type: &svcconfig.Transport_Pubsub{ |
| 236 » » » » Pubsub: &svcconfig.Transport_PubSub{ |
| 237 » » » » » Project: projectName, |
| 238 » » » » » Topic: "test-topic", |
| 239 » » » » }, |
| 240 » » » }, |
| 241 » » } |
| 242 » » cfg.Coordinator = &svcconfig.Coordinator{ |
| 243 » » » Project: projectName, |
| 215 AdminAuthGroup: "admin", | 244 AdminAuthGroup: "admin", |
| 216 ServiceAuthGroup: "services", | 245 ServiceAuthGroup: "services", |
| 217 } | 246 } |
| 218 }) | 247 }) |
| 219 | 248 |
| 220 // Setup Tumble. This also adds the two Tumble indexes to datastore. | 249 // Setup Tumble. This also adds the two Tumble indexes to datastore. |
| 221 e.Tumble.EnableDelayedMutations(c) | 250 e.Tumble.EnableDelayedMutations(c) |
| 222 | 251 |
| 223 tcfg := e.Tumble.GetConfig(c) | 252 tcfg := e.Tumble.GetConfig(c) |
| 224 tcfg.Namespaced = true | 253 tcfg.Namespaced = true |
| 225 e.Tumble.UpdateSettings(c, tcfg) | 254 e.Tumble.UpdateSettings(c, tcfg) |
| 226 | 255 |
| 227 // Install authentication state. | 256 // Install authentication state. |
| 228 c = auth.WithState(c, &e.AuthState) | 257 c = auth.WithState(c, &e.AuthState) |
| 229 | 258 |
| 230 // Setup authentication state. | 259 // Setup authentication state. |
| 231 » e.JoinGroup("all") | 260 » e.LeaveAllGroups() |
| 232 | 261 |
| 233 // Setup our default Coordinator services. | 262 // Setup our default Coordinator services. |
| 234 e.Services = Services{ | 263 e.Services = Services{ |
| 235 IS: func() (storage.Storage, error) { | 264 IS: func() (storage.Storage, error) { |
| 236 return &e.IntermediateStorage, nil | 265 return &e.IntermediateStorage, nil |
| 237 }, | 266 }, |
| 238 GS: func() (gs.Client, error) { | 267 GS: func() (gs.Client, error) { |
| 239 return &e.GSClient, nil | 268 return &e.GSClient, nil |
| 240 }, | 269 }, |
| 241 AP: func() (coordinator.ArchivalPublisher, error) { | 270 AP: func() (coordinator.ArchivalPublisher, error) { |
| 242 return &e.ArchivalPublisher, nil | 271 return &e.ArchivalPublisher, nil |
| 243 }, | 272 }, |
| 244 } | 273 } |
| 245 c = coordinator.WithServices(c, &e.Services) | 274 c = coordinator.WithServices(c, &e.Services) |
| 246 | 275 |
| 247 return c, &e | 276 return c, &e |
| 248 } | 277 } |
| 249 | 278 |
| 250 // WithProjectNamespace runs f in proj's namespace, bypassing authentication | 279 // WithProjectNamespace runs f in proj's namespace, bypassing authentication |
| 251 // checks. | 280 // checks. |
| 252 func WithProjectNamespace(c context.Context, proj luciConfig.ProjectName, f func
(context.Context)) { | 281 func WithProjectNamespace(c context.Context, proj luciConfig.ProjectName, f func
(context.Context)) { |
| 253 if err := coordinator.WithProjectNamespace(&c, proj, coordinator.Namespa
ceAccessNoAuth); err != nil { | 282 if err := coordinator.WithProjectNamespace(&c, proj, coordinator.Namespa
ceAccessNoAuth); err != nil { |
| 254 panic(err) | 283 panic(err) |
| 255 } | 284 } |
| 256 f(c) | 285 f(c) |
| 257 } | 286 } |
| OLD | NEW |