github.com/vmware/govmomi@v0.43.0/vim25/soap/client_test.go (about)

     1  /*
     2  Copyright (c) 2015 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package soap
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"net/http"
    23  	"net/url"
    24  	"os"
    25  	"reflect"
    26  	"testing"
    27  )
    28  
    29  type mockRT struct{}
    30  
    31  func (m mockRT) RoundTrip(req *http.Request) (*http.Response, error) {
    32  	var res http.Response
    33  	res.Header = req.Header.Clone()
    34  	return &res, nil
    35  }
    36  
    37  func TestUserAgent(t *testing.T) {
    38  	tests := []struct {
    39  		name  string
    40  		agent string
    41  	}{
    42  		{name: "default agent", agent: ""},
    43  		{name: "custom agent", agent: "govmomi-test/0.0.0"},
    44  	}
    45  
    46  	const rawURL = "https://vcenter.local"
    47  	u, err := url.Parse(rawURL)
    48  	if err != nil {
    49  		t.Fatalf("parse url: %v", err)
    50  	}
    51  
    52  	for _, test := range tests {
    53  		t.Run(test.name, func(t *testing.T) {
    54  			c := NewClient(u, false)
    55  			c.Transport = &mockRT{}
    56  
    57  			req, err := http.NewRequest(http.MethodPost, rawURL, nil)
    58  			if err != nil {
    59  				t.Fatalf("create request: %v", err)
    60  			}
    61  
    62  			if test.agent != "" {
    63  				c.UserAgent = test.agent
    64  			}
    65  
    66  			if err = c.Do(context.Background(), req, func(response *http.Response) error {
    67  				got := response.Header.Get("user-agent")
    68  				want := func() string {
    69  					if test.agent == "" {
    70  						return defaultUserAgent
    71  					}
    72  					return test.agent
    73  				}
    74  
    75  				if got != want() {
    76  					return fmt.Errorf("user-agent header mismatch: got=%s want=%s", got, want())
    77  				}
    78  				return nil
    79  			}); err != nil {
    80  				t.Errorf("user-agent header validation failed: %v", err)
    81  			}
    82  		})
    83  	}
    84  }
    85  
    86  func TestSplitHostPort(t *testing.T) {
    87  	tests := []struct {
    88  		url  string
    89  		host string
    90  		port string
    91  	}{
    92  		{"127.0.0.1", "127.0.0.1", ""},
    93  		{"*:1234", "*", "1234"},
    94  		{"127.0.0.1:80", "127.0.0.1", "80"},
    95  		{"[::1]:6767", "[::1]", "6767"},
    96  		{"[::1]", "[::1]", ""},
    97  	}
    98  
    99  	for _, test := range tests {
   100  		host, port := splitHostPort(test.url)
   101  		if host != test.host {
   102  			t.Errorf("(%s) %s != %s", test.url, host, test.host)
   103  		}
   104  		if port != test.port {
   105  			t.Errorf("(%s) %s != %s", test.url, port, test.port)
   106  		}
   107  	}
   108  }
   109  
   110  func TestMultipleCAPaths(t *testing.T) {
   111  	err := setCAsOnClient("fixtures/invalid-cert.pem:fixtures/valid-cert.pem")
   112  
   113  	certErr, ok := err.(errInvalidCACertificate)
   114  	if !ok {
   115  		t.Fatalf("Expected errInvalidCACertificate to occur")
   116  	}
   117  	if certErr.File != "fixtures/invalid-cert.pem" {
   118  		t.Fatalf("Expected Err to show invalid file")
   119  	}
   120  }
   121  
   122  func TestInvalidRootCAPath(t *testing.T) {
   123  	err := setCAsOnClient("fixtures/there-is-no-such-file")
   124  
   125  	if _, ok := err.(*os.PathError); !ok {
   126  		t.Fatalf("os.PathError should have occurred: %#v", err)
   127  	}
   128  }
   129  
   130  func TestValidRootCAs(t *testing.T) {
   131  	err := setCAsOnClient("fixtures/valid-cert.pem")
   132  	if err != nil {
   133  		t.Fatalf("Err should not have occurred: %#v", err)
   134  	}
   135  }
   136  
   137  func TestInvalidRootCAs(t *testing.T) {
   138  	err := setCAsOnClient("fixtures/invalid-cert.pem")
   139  
   140  	certErr, ok := err.(errInvalidCACertificate)
   141  	if !ok {
   142  		t.Fatalf("Expected errInvalidCACertificate to occur")
   143  	}
   144  	if certErr.File != "fixtures/invalid-cert.pem" {
   145  		t.Fatalf("Expected Err to show invalid file")
   146  	}
   147  }
   148  
   149  func setCAsOnClient(cas string) error {
   150  	url := &url.URL{
   151  		Scheme: "https",
   152  		Host:   "some.host.tld:8080",
   153  	}
   154  	insecure := false
   155  
   156  	client := NewClient(url, insecure)
   157  
   158  	return client.SetRootCAs(cas)
   159  }
   160  
   161  func TestParseURL(t *testing.T) {
   162  	tests := []struct {
   163  		name    string
   164  		s       string
   165  		want    *url.URL
   166  		wantErr bool
   167  	}{
   168  		{
   169  			name: "empty URL should return null",
   170  			want: nil,
   171  		},
   172  		{
   173  			name: "just endpoint should return full URL",
   174  			s:    "some.vcenter.tld",
   175  			want: &url.URL{
   176  				Scheme: "https",
   177  				Path:   "/sdk",
   178  				Host:   "some.vcenter.tld",
   179  				User:   url.UserPassword("", ""),
   180  			},
   181  		},
   182  		{
   183  			name: "URL with / on suffix should be trimmed",
   184  			s:    "https://some.vcenter.tld/",
   185  			want: &url.URL{
   186  				Scheme: "https",
   187  				Path:   "/sdk",
   188  				Host:   "some.vcenter.tld",
   189  				User:   url.UserPassword("", ""),
   190  			},
   191  		},
   192  		{
   193  			name: "URL with user and password should be used",
   194  			s:    "https://user:password@some.vcenter.tld",
   195  			want: &url.URL{
   196  				Scheme: "https",
   197  				Path:   "/sdk",
   198  				Host:   "some.vcenter.tld",
   199  				User:   url.UserPassword("user", "password"),
   200  			},
   201  		},
   202  		{
   203  			name: "existing path should be used",
   204  			s:    "https://some.vcenter.tld/othersdk",
   205  			want: &url.URL{
   206  				Scheme: "https",
   207  				Path:   "/othersdk",
   208  				Host:   "some.vcenter.tld",
   209  				User:   url.UserPassword("", ""),
   210  			},
   211  		},
   212  		{
   213  			name:    "Invalid URL should be rejected",
   214  			s:       "https://user:password@some.vcenter.tld:xpto1234",
   215  			want:    nil,
   216  			wantErr: true,
   217  		},
   218  	}
   219  	for _, tt := range tests {
   220  		t.Run(tt.name, func(t *testing.T) {
   221  			got, err := ParseURL(tt.s)
   222  			if (err != nil) != tt.wantErr {
   223  				t.Errorf("ParseURL() error = %v, wantErr %v", err, tt.wantErr)
   224  				return
   225  			}
   226  			if !reflect.DeepEqual(got, tt.want) {
   227  				t.Errorf("ParseURL() = %v, want %v", got, tt.want)
   228  			}
   229  		})
   230  	}
   231  }