| Samuel A. Falvo II | fd78c30 | 2013-06-25 16:35:32 -0700 | [diff] [blame] | 1 | package gophercloud | 
 | 2 |  | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 3 | import ( | 
 | 4 | 	"net/http" | 
 | 5 | ) | 
 | 6 |  | 
| Samuel A. Falvo II | 2e2b877 | 2013-07-04 15:40:15 -0700 | [diff] [blame] | 7 | // Provider structures exist for each tangible provider of OpenStack service. | 
 | 8 | // For example, Rackspace, Hewlett-Packard, and NASA might have their own instance of this structure. | 
 | 9 | // | 
 | 10 | // At a minimum, a provider must expose an authentication endpoint. | 
 | 11 | type Provider struct { | 
 | 12 | 	AuthEndpoint string | 
 | 13 | } | 
 | 14 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 15 | // Context structures encapsulate Gophercloud-global state in a manner which | 
 | 16 | // facilitates easier unit testing.  As a user of this SDK, you'll never | 
 | 17 | // have to use this structure, except when contributing new code to the SDK. | 
| Samuel A. Falvo II | fd78c30 | 2013-06-25 16:35:32 -0700 | [diff] [blame] | 18 | type Context struct { | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 19 | 	// providerMap serves as a directory of supported providers. | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 20 | 	providerMap map[string]Provider | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 21 |  | 
 | 22 | 	// httpClient refers to the current HTTP client interface to use. | 
 | 23 | 	httpClient *http.Client | 
| Samuel A. Falvo II | fd78c30 | 2013-06-25 16:35:32 -0700 | [diff] [blame] | 24 | } | 
 | 25 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 26 | // TestContext yields a new Context instance, pre-initialized with a barren | 
 | 27 | // state suitable for per-unit-test customization.  This configuration consists | 
 | 28 | // of: | 
 | 29 | // | 
 | 30 | // * An empty provider map. | 
 | 31 | // | 
 | 32 | // * An HTTP client built by the net/http package (see http://godoc.org/net/http#Client). | 
| Samuel A. Falvo II | fd78c30 | 2013-06-25 16:35:32 -0700 | [diff] [blame] | 33 | func TestContext() *Context { | 
 | 34 | 	return &Context{ | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 35 | 		providerMap: make(map[string]Provider), | 
| Samuel A. Falvo II | 839428e | 2013-06-25 18:02:24 -0700 | [diff] [blame] | 36 | 		httpClient:  &http.Client{}, | 
| Samuel A. Falvo II | fd78c30 | 2013-06-25 16:35:32 -0700 | [diff] [blame] | 37 | 	} | 
 | 38 | } | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 39 |  | 
| Samuel A. Falvo II | 4e89518 | 2013-06-26 15:44:18 -0700 | [diff] [blame] | 40 | // UseCustomClient configures the context to use a customized HTTP client | 
 | 41 | // instance.  By default, TestContext() will return a Context which uses | 
| Samuel A. Falvo II | fca35b7 | 2013-07-02 18:30:28 -0700 | [diff] [blame] | 42 | // the net/http package's default client instance. | 
| Samuel A. Falvo II | 2e2b877 | 2013-07-04 15:40:15 -0700 | [diff] [blame] | 43 | func (c *Context) UseCustomClient(hc *http.Client) *Context { | 
| Samuel A. Falvo II | 839428e | 2013-06-25 18:02:24 -0700 | [diff] [blame] | 44 | 	c.httpClient = hc | 
| Samuel A. Falvo II | 2e2b877 | 2013-07-04 15:40:15 -0700 | [diff] [blame] | 45 | 	return c | 
 | 46 | } | 
 | 47 |  | 
 | 48 | // RegisterProvider allows a unit test to register a mythical provider convenient for testing. | 
 | 49 | // If the provider structure lacks adequate configuration, or the configuration given has some | 
 | 50 | // detectable error, an ErrConfiguration error will result. | 
 | 51 | func (c *Context) RegisterProvider(name string, p Provider) error { | 
 | 52 | 	if p.AuthEndpoint == "" { | 
 | 53 | 		return ErrConfiguration | 
 | 54 | 	} | 
 | 55 |  | 
 | 56 | 	c.providerMap[name] = p | 
 | 57 | 	return nil | 
 | 58 | } | 
 | 59 |  | 
 | 60 | // WithProvider offers convenience for unit tests. | 
 | 61 | func (c *Context) WithProvider(name string, p Provider) *Context { | 
 | 62 | 	err := c.RegisterProvider(name, p) | 
 | 63 | 	if err != nil { | 
 | 64 | 		panic(err) | 
 | 65 | 	} | 
 | 66 | 	return c | 
 | 67 | } | 
 | 68 |  | 
 | 69 | // ProviderByName will locate a provider amongst those previously registered, if it exists. | 
 | 70 | // If the named provider has not been registered, an ErrProvider error will result. | 
 | 71 | func (c *Context) ProviderByName(name string) (p Provider, err error) { | 
 | 72 | 	for provider, descriptor := range c.providerMap { | 
 | 73 | 		if name == provider { | 
 | 74 | 			return descriptor, nil | 
 | 75 | 		} | 
 | 76 | 	} | 
 | 77 | 	return Provider{}, ErrProvider | 
 | 78 | } | 
 | 79 |  | 
| Samuel A. Falvo II | 1dd740a | 2013-07-08 15:48:40 -0700 | [diff] [blame] | 80 | // Instantiates a Cloud Servers API for the provider given. | 
 | 81 | func (c *Context) ServersApi(acc AccessProvider, criteria ApiCriteria) (CloudServersProvider, error) { | 
| Samuel A. Falvo II | 2e2b877 | 2013-07-04 15:40:15 -0700 | [diff] [blame] | 82 | 	url := acc.FirstEndpointUrlByCriteria(criteria) | 
 | 83 | 	if url == "" { | 
 | 84 | 		return nil, ErrEndpoint | 
 | 85 | 	} | 
 | 86 |  | 
| Samuel A. Falvo II | 1dd740a | 2013-07-08 15:48:40 -0700 | [diff] [blame] | 87 | 	gcp := &genericServersProvider{ | 
| Samuel A. Falvo II | 2e2b877 | 2013-07-04 15:40:15 -0700 | [diff] [blame] | 88 | 		endpoint: url, | 
 | 89 | 		context:  c, | 
| Samuel A. Falvo II | bc0d54a | 2013-07-08 14:45:21 -0700 | [diff] [blame] | 90 | 		access:   acc, | 
| Samuel A. Falvo II | 2e2b877 | 2013-07-04 15:40:15 -0700 | [diff] [blame] | 91 | 	} | 
 | 92 |  | 
 | 93 | 	return gcp, nil | 
| Samuel A. Falvo II | 5d0d74c | 2013-06-25 17:23:18 -0700 | [diff] [blame] | 94 | } |