metadata: Refactor common parts out of ec2
This commit is contained in:
		| @@ -1,10 +1,5 @@ | ||||
| package datasource | ||||
|  | ||||
| const ( | ||||
| 	Ec2ApiVersion       = "2009-04-04" | ||||
| 	OpenstackApiVersion = "2012-08-10" | ||||
| ) | ||||
|  | ||||
| type Datasource interface { | ||||
| 	IsAvailable() bool | ||||
| 	AvailabilityChanges() bool | ||||
|   | ||||
| @@ -7,44 +7,28 @@ import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/coreos/coreos-cloudinit/datasource/metadata" | ||||
| 	"github.com/coreos/coreos-cloudinit/pkg" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	DefaultAddress = "http://169.254.169.254/" | ||||
| 	apiVersion     = "2009-04-04" | ||||
| 	userdataUrl    = apiVersion + "/user-data" | ||||
| 	metadataUrl    = apiVersion + "/meta-data" | ||||
| 	userdataPath   = apiVersion + "/user-data" | ||||
| 	metadataPath   = apiVersion + "/meta-data" | ||||
| ) | ||||
|  | ||||
| type metadataService struct { | ||||
| 	root   string | ||||
| 	client pkg.Getter | ||||
| 	metadata.MetadataService | ||||
| } | ||||
|  | ||||
| func NewDatasource(root string) *metadataService { | ||||
| 	if !strings.HasSuffix(root, "/") { | ||||
| 		root += "/" | ||||
| 	} | ||||
| 	return &metadataService{root, pkg.NewHttpClient()} | ||||
| } | ||||
|  | ||||
| func (ms metadataService) IsAvailable() bool { | ||||
| 	_, err := ms.client.Get(ms.root + apiVersion) | ||||
| 	return (err == nil) | ||||
| } | ||||
|  | ||||
| func (ms metadataService) AvailabilityChanges() bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (ms metadataService) ConfigRoot() string { | ||||
| 	return ms.root | ||||
| 	return &metadataService{metadata.NewDatasource(root, apiVersion, userdataPath, metadataPath)} | ||||
| } | ||||
|  | ||||
| func (ms metadataService) FetchMetadata() ([]byte, error) { | ||||
| 	attrs := make(map[string]interface{}) | ||||
| 	if keynames, err := fetchAttributes(ms.client, fmt.Sprintf("%s/public-keys", ms.metadataUrl())); err == nil { | ||||
| 	if keynames, err := ms.fetchAttributes(fmt.Sprintf("%s/public-keys", ms.MetadataUrl())); err == nil { | ||||
| 		keyIDs := make(map[string]string) | ||||
| 		for _, keyname := range keynames { | ||||
| 			tokens := strings.SplitN(keyname, "=", 2) | ||||
| @@ -56,7 +40,7 @@ func (ms metadataService) FetchMetadata() ([]byte, error) { | ||||
|  | ||||
| 		keys := make(map[string]string) | ||||
| 		for name, id := range keyIDs { | ||||
| 			sshkey, err := fetchAttribute(ms.client, fmt.Sprintf("%s/public-keys/%s/openssh-key", ms.metadataUrl(), id)) | ||||
| 			sshkey, err := ms.fetchAttribute(fmt.Sprintf("%s/public-keys/%s/openssh-key", ms.MetadataUrl(), id)) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| @@ -68,25 +52,25 @@ func (ms metadataService) FetchMetadata() ([]byte, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if hostname, err := fetchAttribute(ms.client, fmt.Sprintf("%s/hostname", ms.metadataUrl())); err == nil { | ||||
| 	if hostname, err := ms.fetchAttribute(fmt.Sprintf("%s/hostname", ms.MetadataUrl())); err == nil { | ||||
| 		attrs["hostname"] = hostname | ||||
| 	} else if _, ok := err.(pkg.ErrNotFound); !ok { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if localAddr, err := fetchAttribute(ms.client, fmt.Sprintf("%s/local-ipv4", ms.metadataUrl())); err == nil { | ||||
| 	if localAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/local-ipv4", ms.MetadataUrl())); err == nil { | ||||
| 		attrs["local-ipv4"] = localAddr | ||||
| 	} else if _, ok := err.(pkg.ErrNotFound); !ok { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if publicAddr, err := fetchAttribute(ms.client, fmt.Sprintf("%s/public-ipv4", ms.metadataUrl())); err == nil { | ||||
| 	if publicAddr, err := ms.fetchAttribute(fmt.Sprintf("%s/public-ipv4", ms.MetadataUrl())); err == nil { | ||||
| 		attrs["public-ipv4"] = publicAddr | ||||
| 	} else if _, ok := err.(pkg.ErrNotFound); !ok { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if content_path, err := fetchAttribute(ms.client, fmt.Sprintf("%s/network_config/content_path", ms.metadataUrl())); err == nil { | ||||
| 	if content_path, err := ms.fetchAttribute(fmt.Sprintf("%s/network_config/content_path", ms.MetadataUrl())); err == nil { | ||||
| 		attrs["network_config"] = map[string]string{ | ||||
| 			"content_path": content_path, | ||||
| 		} | ||||
| @@ -97,30 +81,12 @@ func (ms metadataService) FetchMetadata() ([]byte, error) { | ||||
| 	return json.Marshal(attrs) | ||||
| } | ||||
|  | ||||
| func (ms metadataService) FetchUserdata() ([]byte, error) { | ||||
| 	if data, err := ms.client.GetRetry(ms.userdataUrl()); err == nil { | ||||
| 		return data, err | ||||
| 	} else if _, ok := err.(pkg.ErrNotFound); ok { | ||||
| 		return []byte{}, nil | ||||
| 	} else { | ||||
| 		return data, err | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (ms metadataService) Type() string { | ||||
| 	return "ec2-metadata-service" | ||||
| } | ||||
|  | ||||
| func (ms metadataService) metadataUrl() string { | ||||
| 	return (ms.root + metadataUrl) | ||||
| } | ||||
|  | ||||
| func (ms metadataService) userdataUrl() string { | ||||
| 	return (ms.root + userdataUrl) | ||||
| } | ||||
|  | ||||
| func fetchAttributes(client pkg.Getter, url string) ([]string, error) { | ||||
| 	resp, err := client.GetRetry(url) | ||||
| func (ms metadataService) fetchAttributes(url string) ([]string, error) { | ||||
| 	resp, err := ms.FetchData(url) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -132,8 +98,8 @@ func fetchAttributes(client pkg.Getter, url string) ([]string, error) { | ||||
| 	return data, scanner.Err() | ||||
| } | ||||
|  | ||||
| func fetchAttribute(client pkg.Getter, url string) (string, error) { | ||||
| 	if attrs, err := fetchAttributes(client, url); err == nil && len(attrs) > 0 { | ||||
| func (ms metadataService) fetchAttribute(url string) (string, error) { | ||||
| 	if attrs, err := ms.fetchAttributes(url); err == nil && len(attrs) > 0 { | ||||
| 		return attrs[0], nil | ||||
| 	} else { | ||||
| 		return "", err | ||||
|   | ||||
| @@ -6,36 +6,11 @@ import ( | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/coreos/coreos-cloudinit/datasource/metadata" | ||||
| 	"github.com/coreos/coreos-cloudinit/datasource/metadata/test" | ||||
| 	"github.com/coreos/coreos-cloudinit/pkg" | ||||
| ) | ||||
|  | ||||
| type testHttpClient struct { | ||||
| 	resources map[string]string | ||||
| 	err       error | ||||
| } | ||||
|  | ||||
| func (t *testHttpClient) GetRetry(url string) ([]byte, error) { | ||||
| 	if t.err != nil { | ||||
| 		return nil, t.err | ||||
| 	} | ||||
| 	if val, ok := t.resources[url]; ok { | ||||
| 		return []byte(val), nil | ||||
| 	} else { | ||||
| 		return nil, pkg.ErrNotFound{fmt.Errorf("not found: %q", url)} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (t *testHttpClient) Get(url string) ([]byte, error) { | ||||
| 	return t.GetRetry(url) | ||||
| } | ||||
|  | ||||
| func TestAvailabilityChanges(t *testing.T) { | ||||
| 	want := true | ||||
| 	if ac := (metadataService{}).AvailabilityChanges(); ac != want { | ||||
| 		t.Fatalf("bad AvailabilityChanges: want %q, got %q", want, ac) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestType(t *testing.T) { | ||||
| 	want := "ec2-metadata-service" | ||||
| 	if kind := (metadataService{}).Type(); kind != want { | ||||
| @@ -43,102 +18,6 @@ func TestType(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestIsAvailable(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root      string | ||||
| 		resources map[string]string | ||||
| 		expect    bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root: "/", | ||||
| 			resources: map[string]string{ | ||||
| 				"/2009-04-04": "", | ||||
| 			}, | ||||
| 			expect: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:      "/", | ||||
| 			resources: map[string]string{}, | ||||
| 			expect:    false, | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := &metadataService{tt.root, &testHttpClient{tt.resources, nil}} | ||||
| 		if a := service.IsAvailable(); a != tt.expect { | ||||
| 			t.Fatalf("bad isAvailable (%q): want %q, got %q", tt.resources, tt.expect, a) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestFetchUserdata(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root      string | ||||
| 		resources map[string]string | ||||
| 		userdata  []byte | ||||
| 		clientErr error | ||||
| 		expectErr error | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root: "/", | ||||
| 			resources: map[string]string{ | ||||
| 				"/2009-04-04/user-data": "hello", | ||||
| 			}, | ||||
| 			userdata: []byte("hello"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:      "/", | ||||
| 			clientErr: pkg.ErrNotFound{fmt.Errorf("test not found error")}, | ||||
| 			userdata:  []byte{}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:      "/", | ||||
| 			clientErr: pkg.ErrTimeout{fmt.Errorf("test timeout error")}, | ||||
| 			expectErr: pkg.ErrTimeout{fmt.Errorf("test timeout error")}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := &metadataService{tt.root, &testHttpClient{tt.resources, tt.clientErr}} | ||||
| 		data, err := service.FetchUserdata() | ||||
| 		if Error(err) != Error(tt.expectErr) { | ||||
| 			t.Fatalf("bad error (%q): want %q, got %q", tt.resources, tt.expectErr, err) | ||||
| 		} | ||||
| 		if !bytes.Equal(data, tt.userdata) { | ||||
| 			t.Fatalf("bad userdata (%q): want %q, got %q", tt.resources, tt.userdata, data) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestUrls(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root       string | ||||
| 		expectRoot string | ||||
| 		userdata   string | ||||
| 		metadata   string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root:       "/", | ||||
| 			expectRoot: "/", | ||||
| 			userdata:   "/2009-04-04/user-data", | ||||
| 			metadata:   "/2009-04-04/meta-data", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:       "http://169.254.169.254/", | ||||
| 			expectRoot: "http://169.254.169.254/", | ||||
| 			userdata:   "http://169.254.169.254/2009-04-04/user-data", | ||||
| 			metadata:   "http://169.254.169.254/2009-04-04/meta-data", | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := &metadataService{tt.root, nil} | ||||
| 		if url := service.userdataUrl(); url != tt.userdata { | ||||
| 			t.Fatalf("bad url (%q): want %q, got %q", tt.root, tt.userdata, url) | ||||
| 		} | ||||
| 		if url := service.metadataUrl(); url != tt.metadata { | ||||
| 			t.Fatalf("bad url (%q): want %q, got %q", tt.root, tt.metadata, url) | ||||
| 		} | ||||
| 		if url := service.ConfigRoot(); url != tt.expectRoot { | ||||
| 			t.Fatalf("bad url (%q): want %q, got %q", tt.root, tt.expectRoot, url) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestFetchAttributes(t *testing.T) { | ||||
| 	for _, s := range []struct { | ||||
| 		resources map[string]string | ||||
| @@ -169,7 +48,7 @@ func TestFetchAttributes(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			err: pkg.ErrNotFound{fmt.Errorf("test error")}, | ||||
| 			err: fmt.Errorf("test error"), | ||||
| 			tests: []struct { | ||||
| 				path string | ||||
| 				val  []string | ||||
| @@ -178,9 +57,11 @@ func TestFetchAttributes(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		client := &testHttpClient{s.resources, s.err} | ||||
| 		service := metadataService{metadata.MetadataService{ | ||||
| 			Client: &test.HttpClient{s.resources, s.err}, | ||||
| 		}} | ||||
| 		for _, tt := range s.tests { | ||||
| 			attrs, err := fetchAttributes(client, tt.path) | ||||
| 			attrs, err := service.fetchAttributes(tt.path) | ||||
| 			if err != s.err { | ||||
| 				t.Fatalf("bad error for %q (%q): want %q, got %q", tt.path, s.resources, s.err, err) | ||||
| 			} | ||||
| @@ -221,7 +102,7 @@ func TestFetchAttribute(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			err: pkg.ErrNotFound{fmt.Errorf("test error")}, | ||||
| 			err: fmt.Errorf("test error"), | ||||
| 			tests: []struct { | ||||
| 				path string | ||||
| 				val  string | ||||
| @@ -230,9 +111,11 @@ func TestFetchAttribute(t *testing.T) { | ||||
| 			}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		client := &testHttpClient{s.resources, s.err} | ||||
| 		service := metadataService{metadata.MetadataService{ | ||||
| 			Client: &test.HttpClient{s.resources, s.err}, | ||||
| 		}} | ||||
| 		for _, tt := range s.tests { | ||||
| 			attr, err := fetchAttribute(client, tt.path) | ||||
| 			attr, err := service.fetchAttribute(tt.path) | ||||
| 			if err != s.err { | ||||
| 				t.Fatalf("bad error for %q (%q): want %q, got %q", tt.path, s.resources, s.err, err) | ||||
| 			} | ||||
| @@ -245,21 +128,24 @@ func TestFetchAttribute(t *testing.T) { | ||||
|  | ||||
| func TestFetchMetadata(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root      string | ||||
| 		resources map[string]string | ||||
| 		expect    []byte | ||||
| 		clientErr error | ||||
| 		expectErr error | ||||
| 		root         string | ||||
| 		metadataPath string | ||||
| 		resources    map[string]string | ||||
| 		expect       []byte | ||||
| 		clientErr    error | ||||
| 		expectErr    error | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root: "/", | ||||
| 			root:         "/", | ||||
| 			metadataPath: "2009-04-04/meta-data", | ||||
| 			resources: map[string]string{ | ||||
| 				"/2009-04-04/meta-data/public-keys": "bad\n", | ||||
| 			}, | ||||
| 			expectErr: fmt.Errorf("malformed public key: \"bad\""), | ||||
| 		}, | ||||
| 		{ | ||||
| 			root: "/", | ||||
| 			root:         "/", | ||||
| 			metadataPath: "2009-04-04/meta-data", | ||||
| 			resources: map[string]string{ | ||||
| 				"/2009-04-04/meta-data/hostname":                    "host", | ||||
| 				"/2009-04-04/meta-data/local-ipv4":                  "1.2.3.4", | ||||
| @@ -276,7 +162,11 @@ func TestFetchMetadata(t *testing.T) { | ||||
| 			expectErr: pkg.ErrTimeout{fmt.Errorf("test error")}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := &metadataService{tt.root, &testHttpClient{tt.resources, tt.clientErr}} | ||||
| 		service := &metadataService{metadata.MetadataService{ | ||||
| 			Root:         tt.root, | ||||
| 			Client:       &test.HttpClient{tt.resources, tt.clientErr}, | ||||
| 			MetadataPath: tt.metadataPath, | ||||
| 		}} | ||||
| 		metadata, err := service.FetchMetadata() | ||||
| 		if Error(err) != Error(tt.expectErr) { | ||||
| 			t.Fatalf("bad error (%q): want %q, got %q", tt.resources, tt.expectErr, err) | ||||
| @@ -287,35 +177,6 @@ func TestFetchMetadata(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestNewDatasource(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root       string | ||||
| 		expectRoot string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root:       "", | ||||
| 			expectRoot: "/", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:       "/", | ||||
| 			expectRoot: "/", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:       "http://169.254.169.254", | ||||
| 			expectRoot: "http://169.254.169.254/", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:       "http://169.254.169.254/", | ||||
| 			expectRoot: "http://169.254.169.254/", | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := NewDatasource(tt.root) | ||||
| 		if service.root != tt.expectRoot { | ||||
| 			t.Fatalf("bad root (%q): want %q, got %q", tt.root, tt.expectRoot, service.root) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Error(err error) string { | ||||
| 	if err != nil { | ||||
| 		return err.Error() | ||||
|   | ||||
							
								
								
									
										57
									
								
								datasource/metadata/metadata.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								datasource/metadata/metadata.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| package metadata | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/coreos/coreos-cloudinit/pkg" | ||||
| ) | ||||
|  | ||||
| type MetadataService struct { | ||||
| 	Root         string | ||||
| 	Client       pkg.Getter | ||||
| 	ApiVersion   string | ||||
| 	UserdataPath string | ||||
| 	MetadataPath string | ||||
| } | ||||
|  | ||||
| func NewDatasource(root, apiVersion, userdataPath, metadataPath string) MetadataService { | ||||
| 	if !strings.HasSuffix(root, "/") { | ||||
| 		root += "/" | ||||
| 	} | ||||
| 	return MetadataService{root, pkg.NewHttpClient(), apiVersion, userdataPath, metadataPath} | ||||
| } | ||||
|  | ||||
| func (ms MetadataService) IsAvailable() bool { | ||||
| 	_, err := ms.Client.Get(ms.Root + ms.ApiVersion) | ||||
| 	return (err == nil) | ||||
| } | ||||
|  | ||||
| func (ms MetadataService) AvailabilityChanges() bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func (ms MetadataService) ConfigRoot() string { | ||||
| 	return ms.Root | ||||
| } | ||||
|  | ||||
| func (ms MetadataService) FetchUserdata() ([]byte, error) { | ||||
| 	return ms.FetchData(ms.UserdataUrl()) | ||||
| } | ||||
|  | ||||
| func (ms MetadataService) FetchData(url string) ([]byte, error) { | ||||
| 	if data, err := ms.Client.GetRetry(url); err == nil { | ||||
| 		return data, err | ||||
| 	} else if _, ok := err.(pkg.ErrNotFound); ok { | ||||
| 		return []byte{}, nil | ||||
| 	} else { | ||||
| 		return data, err | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (ms MetadataService) MetadataUrl() string { | ||||
| 	return (ms.Root + ms.MetadataPath) | ||||
| } | ||||
|  | ||||
| func (ms MetadataService) UserdataUrl() string { | ||||
| 	return (ms.Root + ms.UserdataPath) | ||||
| } | ||||
							
								
								
									
										171
									
								
								datasource/metadata/metadata_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								datasource/metadata/metadata_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | ||||
| package metadata | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/coreos/coreos-cloudinit/datasource/metadata/test" | ||||
| 	"github.com/coreos/coreos-cloudinit/pkg" | ||||
| ) | ||||
|  | ||||
| func TestAvailabilityChanges(t *testing.T) { | ||||
| 	want := true | ||||
| 	if ac := (MetadataService{}).AvailabilityChanges(); ac != want { | ||||
| 		t.Fatalf("bad AvailabilityChanges: want %q, got %q", want, ac) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestIsAvailable(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root       string | ||||
| 		apiVersion string | ||||
| 		resources  map[string]string | ||||
| 		expect     bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root:       "/", | ||||
| 			apiVersion: "2009-04-04", | ||||
| 			resources: map[string]string{ | ||||
| 				"/2009-04-04": "", | ||||
| 			}, | ||||
| 			expect: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:      "/", | ||||
| 			resources: map[string]string{}, | ||||
| 			expect:    false, | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := &MetadataService{ | ||||
| 			Root:       tt.root, | ||||
| 			Client:     &test.HttpClient{tt.resources, nil}, | ||||
| 			ApiVersion: tt.apiVersion, | ||||
| 		} | ||||
| 		if a := service.IsAvailable(); a != tt.expect { | ||||
| 			t.Fatalf("bad isAvailable (%q): want %q, got %q", tt.resources, tt.expect, a) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestFetchUserdata(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root         string | ||||
| 		userdataPath string | ||||
| 		resources    map[string]string | ||||
| 		userdata     []byte | ||||
| 		clientErr    error | ||||
| 		expectErr    error | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root:         "/", | ||||
| 			userdataPath: "2009-04-04/user-data", | ||||
| 			resources: map[string]string{ | ||||
| 				"/2009-04-04/user-data": "hello", | ||||
| 			}, | ||||
| 			userdata: []byte("hello"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:      "/", | ||||
| 			clientErr: pkg.ErrNotFound{fmt.Errorf("test not found error")}, | ||||
| 			userdata:  []byte{}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:      "/", | ||||
| 			clientErr: pkg.ErrTimeout{fmt.Errorf("test timeout error")}, | ||||
| 			expectErr: pkg.ErrTimeout{fmt.Errorf("test timeout error")}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := &MetadataService{ | ||||
| 			Root:         tt.root, | ||||
| 			Client:       &test.HttpClient{tt.resources, tt.clientErr}, | ||||
| 			UserdataPath: tt.userdataPath, | ||||
| 		} | ||||
| 		data, err := service.FetchUserdata() | ||||
| 		if Error(err) != Error(tt.expectErr) { | ||||
| 			t.Fatalf("bad error (%q): want %q, got %q", tt.resources, tt.expectErr, err) | ||||
| 		} | ||||
| 		if !bytes.Equal(data, tt.userdata) { | ||||
| 			t.Fatalf("bad userdata (%q): want %q, got %q", tt.resources, tt.userdata, data) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestUrls(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root         string | ||||
| 		userdataPath string | ||||
| 		metadataPath string | ||||
| 		expectRoot   string | ||||
| 		userdata     string | ||||
| 		metadata     string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root:         "/", | ||||
| 			userdataPath: "2009-04-04/user-data", | ||||
| 			metadataPath: "2009-04-04/meta-data", | ||||
| 			expectRoot:   "/", | ||||
| 			userdata:     "/2009-04-04/user-data", | ||||
| 			metadata:     "/2009-04-04/meta-data", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:         "http://169.254.169.254/", | ||||
| 			userdataPath: "2009-04-04/user-data", | ||||
| 			metadataPath: "2009-04-04/meta-data", | ||||
| 			expectRoot:   "http://169.254.169.254/", | ||||
| 			userdata:     "http://169.254.169.254/2009-04-04/user-data", | ||||
| 			metadata:     "http://169.254.169.254/2009-04-04/meta-data", | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := &MetadataService{ | ||||
| 			Root:         tt.root, | ||||
| 			UserdataPath: tt.userdataPath, | ||||
| 			MetadataPath: tt.metadataPath, | ||||
| 		} | ||||
| 		if url := service.UserdataUrl(); url != tt.userdata { | ||||
| 			t.Fatalf("bad url (%q): want %q, got %q", tt.root, tt.userdata, url) | ||||
| 		} | ||||
| 		if url := service.MetadataUrl(); url != tt.metadata { | ||||
| 			t.Fatalf("bad url (%q): want %q, got %q", tt.root, tt.metadata, url) | ||||
| 		} | ||||
| 		if url := service.ConfigRoot(); url != tt.expectRoot { | ||||
| 			t.Fatalf("bad url (%q): want %q, got %q", tt.root, tt.expectRoot, url) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestNewDatasource(t *testing.T) { | ||||
| 	for _, tt := range []struct { | ||||
| 		root       string | ||||
| 		expectRoot string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			root:       "", | ||||
| 			expectRoot: "/", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:       "/", | ||||
| 			expectRoot: "/", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:       "http://169.254.169.254", | ||||
| 			expectRoot: "http://169.254.169.254/", | ||||
| 		}, | ||||
| 		{ | ||||
| 			root:       "http://169.254.169.254/", | ||||
| 			expectRoot: "http://169.254.169.254/", | ||||
| 		}, | ||||
| 	} { | ||||
| 		service := NewDatasource(tt.root, "", "", "") | ||||
| 		if service.Root != tt.expectRoot { | ||||
| 			t.Fatalf("bad root (%q): want %q, got %q", tt.root, tt.expectRoot, service.Root) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Error(err error) string { | ||||
| 	if err != nil { | ||||
| 		return err.Error() | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
							
								
								
									
										27
									
								
								datasource/metadata/test/test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								datasource/metadata/test/test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| package test | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/coreos/coreos-cloudinit/pkg" | ||||
| ) | ||||
|  | ||||
| type HttpClient struct { | ||||
| 	Resources map[string]string | ||||
| 	Err       error | ||||
| } | ||||
|  | ||||
| func (t *HttpClient) GetRetry(url string) ([]byte, error) { | ||||
| 	if t.Err != nil { | ||||
| 		return nil, t.Err | ||||
| 	} | ||||
| 	if val, ok := t.Resources[url]; ok { | ||||
| 		return []byte(val), nil | ||||
| 	} else { | ||||
| 		return nil, pkg.ErrNotFound{fmt.Errorf("not found: %q", url)} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (t *HttpClient) Get(url string) ([]byte, error) { | ||||
| 	return t.GetRetry(url) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user