github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/api/api_test.go (about)

     1  package api
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"net/http"
    10  	"os"
    11  	"regexp"
    12  	"runtime"
    13  	"testing"
    14  
    15  	"github.com/docker/docker/pkg/reexec"
    16  	"github.com/docker/libnetwork"
    17  	"github.com/docker/libnetwork/datastore"
    18  	"github.com/docker/libnetwork/netlabel"
    19  	"github.com/docker/libnetwork/options"
    20  	"github.com/docker/libnetwork/testutils"
    21  	"github.com/docker/libnetwork/types"
    22  )
    23  
    24  const (
    25  	bridgeNetType = "bridge"
    26  	bridgeName    = "docker0"
    27  )
    28  
    29  func i2s(i interface{}) string {
    30  	s, ok := i.(string)
    31  	if !ok {
    32  		panic(fmt.Sprintf("Failed i2s for %v", i))
    33  	}
    34  	return s
    35  }
    36  
    37  func i2e(i interface{}) *endpointResource {
    38  	s, ok := i.(*endpointResource)
    39  	if !ok {
    40  		panic(fmt.Sprintf("Failed i2e for %v", i))
    41  	}
    42  	return s
    43  }
    44  
    45  func i2eL(i interface{}) []*endpointResource {
    46  	s, ok := i.([]*endpointResource)
    47  	if !ok {
    48  		panic(fmt.Sprintf("Failed i2eL for %v", i))
    49  	}
    50  	return s
    51  }
    52  
    53  func i2n(i interface{}) *networkResource {
    54  	s, ok := i.(*networkResource)
    55  	if !ok {
    56  		panic(fmt.Sprintf("Failed i2n for %v", i))
    57  	}
    58  	return s
    59  }
    60  
    61  func i2nL(i interface{}) []*networkResource {
    62  	s, ok := i.([]*networkResource)
    63  	if !ok {
    64  		panic(fmt.Sprintf("Failed i2nL for %v", i))
    65  	}
    66  	return s
    67  }
    68  
    69  func i2sb(i interface{}) *sandboxResource {
    70  	s, ok := i.(*sandboxResource)
    71  	if !ok {
    72  		panic(fmt.Sprintf("Failed i2sb for %v", i))
    73  	}
    74  	return s
    75  }
    76  
    77  func i2sbL(i interface{}) []*sandboxResource {
    78  	s, ok := i.([]*sandboxResource)
    79  	if !ok {
    80  		panic(fmt.Sprintf("Failed i2sbL for %v", i))
    81  	}
    82  	return s
    83  }
    84  
    85  func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkController, libnetwork.Network) {
    86  	// Cleanup local datastore file
    87  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
    88  
    89  	c, err := libnetwork.New()
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  
    94  	netOption := options.Generic{
    95  		netlabel.GenericData: options.Generic{
    96  			"BridgeName": network,
    97  		},
    98  	}
    99  	netGeneric := libnetwork.NetworkOptionGeneric(netOption)
   100  	nw, err := c.NewNetwork(bridgeNetType, network, "", netGeneric)
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	return c, nw
   106  }
   107  
   108  func getExposedPorts() []types.TransportPort {
   109  	return []types.TransportPort{
   110  		{Proto: types.TCP, Port: uint16(5000)},
   111  		{Proto: types.UDP, Port: uint16(400)},
   112  		{Proto: types.TCP, Port: uint16(600)},
   113  	}
   114  }
   115  
   116  func getPortMapping() []types.PortBinding {
   117  	return []types.PortBinding{
   118  		{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
   119  		{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
   120  		{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
   121  	}
   122  }
   123  
   124  func TestMain(m *testing.M) {
   125  	if reexec.Init() {
   126  		return
   127  	}
   128  	os.Exit(m.Run())
   129  }
   130  
   131  func TestSandboxOptionParser(t *testing.T) {
   132  	hn := "host1"
   133  	dn := "docker.com"
   134  	hp := "/etc/hosts"
   135  	rc := "/etc/resolv.conf"
   136  	dnss := []string{"8.8.8.8", "172.28.34.5"}
   137  	ehs := []extraHost{{Name: "extra1", Address: "172.28.9.1"}, {Name: "extra2", Address: "172.28.9.2"}}
   138  
   139  	sb := sandboxCreate{
   140  		HostName:          hn,
   141  		DomainName:        dn,
   142  		HostsPath:         hp,
   143  		ResolvConfPath:    rc,
   144  		DNS:               dnss,
   145  		ExtraHosts:        ehs,
   146  		UseDefaultSandbox: true,
   147  	}
   148  
   149  	if len(sb.parseOptions()) != 9 {
   150  		t.Fatalf("Failed to generate all libnetwork.SandboxOption methods")
   151  	}
   152  }
   153  
   154  func TestJson(t *testing.T) {
   155  	nc := networkCreate{NetworkType: bridgeNetType}
   156  	b, err := json.Marshal(nc)
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  
   161  	var ncp networkCreate
   162  	err = json.Unmarshal(b, &ncp)
   163  	if err != nil {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	if nc.NetworkType != ncp.NetworkType {
   168  		t.Fatalf("Incorrect networkCreate after json encoding/deconding: %v", ncp)
   169  	}
   170  
   171  	jl := endpointJoin{SandboxID: "abcdef456789"}
   172  	b, err = json.Marshal(jl)
   173  	if err != nil {
   174  		t.Fatal(err)
   175  	}
   176  
   177  	var jld endpointJoin
   178  	err = json.Unmarshal(b, &jld)
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  
   183  	if jl.SandboxID != jld.SandboxID {
   184  		t.Fatalf("Incorrect endpointJoin after json encoding/deconding: %v", jld)
   185  	}
   186  }
   187  
   188  func TestCreateDeleteNetwork(t *testing.T) {
   189  	defer testutils.SetupTestOSContext(t)()
   190  
   191  	// Cleanup local datastore file
   192  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
   193  
   194  	c, err := libnetwork.New()
   195  	if err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	defer c.Stop()
   199  
   200  	badBody, err := json.Marshal("bad body")
   201  	if err != nil {
   202  		t.Fatal(err)
   203  	}
   204  
   205  	vars := make(map[string]string)
   206  	_, errRsp := procCreateNetwork(c, nil, badBody)
   207  	if errRsp == &createdResponse {
   208  		t.Fatalf("Expected to fail but succeeded")
   209  	}
   210  	if errRsp.StatusCode != http.StatusBadRequest {
   211  		t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp)
   212  	}
   213  
   214  	incompleteBody, err := json.Marshal(networkCreate{})
   215  	if err != nil {
   216  		t.Fatal(err)
   217  	}
   218  
   219  	_, errRsp = procCreateNetwork(c, vars, incompleteBody)
   220  	if errRsp == &createdResponse {
   221  		t.Fatalf("Expected to fail but succeeded")
   222  	}
   223  	if errRsp.StatusCode != http.StatusBadRequest {
   224  		t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp)
   225  	}
   226  
   227  	dops := GetOpsMap("abc", "")
   228  	nops := map[string]string{
   229  		netlabel.EnableIPv6: "true",
   230  	}
   231  	nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops}
   232  	goodBody, err := json.Marshal(nc)
   233  	if err != nil {
   234  		t.Fatal(err)
   235  	}
   236  
   237  	_, errRsp = procCreateNetwork(c, vars, goodBody)
   238  	if errRsp != &createdResponse {
   239  		t.Fatalf("Unexepected failure: %v", errRsp)
   240  	}
   241  
   242  	vars[urlNwName] = ""
   243  	_, errRsp = procDeleteNetwork(c, vars, nil)
   244  	if errRsp == &successResponse {
   245  		t.Fatalf("Expected to fail but succeeded")
   246  	}
   247  
   248  	vars[urlNwName] = "abc"
   249  	_, errRsp = procDeleteNetwork(c, vars, nil)
   250  	if errRsp == &successResponse {
   251  		t.Fatalf("Expected to fail but succeeded")
   252  	}
   253  
   254  	vars[urlNwName] = "network_1"
   255  	_, errRsp = procDeleteNetwork(c, vars, nil)
   256  	if errRsp != &successResponse {
   257  		t.Fatalf("Unexepected failure: %v", errRsp)
   258  	}
   259  }
   260  
   261  func TestGetNetworksAndEndpoints(t *testing.T) {
   262  	defer testutils.SetupTestOSContext(t)()
   263  
   264  	// Cleanup local datastore file
   265  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
   266  
   267  	c, err := libnetwork.New()
   268  	if err != nil {
   269  		t.Fatal(err)
   270  	}
   271  	defer c.Stop()
   272  
   273  	ops := GetOpsMap("api_test_nw", "")
   274  	nc := networkCreate{Name: "sh", NetworkType: bridgeNetType, DriverOpts: ops}
   275  	body, err := json.Marshal(nc)
   276  	if err != nil {
   277  		t.Fatal(err)
   278  	}
   279  
   280  	vars := make(map[string]string)
   281  	inid, errRsp := procCreateNetwork(c, vars, body)
   282  	if errRsp != &createdResponse {
   283  		t.Fatalf("Unexepected failure: %v", errRsp)
   284  	}
   285  	nid, ok := inid.(string)
   286  	if !ok {
   287  		t.FailNow()
   288  	}
   289  
   290  	ec1 := endpointCreate{
   291  		Name: "ep1",
   292  	}
   293  	b1, err := json.Marshal(ec1)
   294  	if err != nil {
   295  		t.Fatal(err)
   296  	}
   297  	ec2 := endpointCreate{Name: "ep2"}
   298  	b2, err := json.Marshal(ec2)
   299  	if err != nil {
   300  		t.Fatal(err)
   301  	}
   302  
   303  	vars[urlNwName] = "sh"
   304  	vars[urlEpName] = "ep1"
   305  	ieid1, errRsp := procCreateEndpoint(c, vars, b1)
   306  	if errRsp != &createdResponse {
   307  		t.Fatalf("Unexepected failure: %v", errRsp)
   308  	}
   309  	eid1 := i2s(ieid1)
   310  	vars[urlEpName] = "ep2"
   311  	ieid2, errRsp := procCreateEndpoint(c, vars, b2)
   312  	if errRsp != &createdResponse {
   313  		t.Fatalf("Unexepected failure: %v", errRsp)
   314  	}
   315  	eid2 := i2s(ieid2)
   316  
   317  	vars[urlNwName] = ""
   318  	vars[urlEpName] = "ep1"
   319  	_, errRsp = procGetEndpoint(c, vars, nil)
   320  	if errRsp == &successResponse {
   321  		t.Fatalf("Expected failure but succeeded: %v", errRsp)
   322  	}
   323  	if errRsp.StatusCode != http.StatusBadRequest {
   324  		t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode)
   325  	}
   326  
   327  	vars = make(map[string]string)
   328  	vars[urlNwName] = "sh"
   329  	vars[urlEpID] = ""
   330  	_, errRsp = procGetEndpoint(c, vars, nil)
   331  	if errRsp == &successResponse {
   332  		t.Fatalf("Expected failure but succeeded: %v", errRsp)
   333  	}
   334  	if errRsp.StatusCode != http.StatusBadRequest {
   335  		t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode)
   336  	}
   337  
   338  	vars = make(map[string]string)
   339  	vars[urlNwID] = ""
   340  	vars[urlEpID] = eid1
   341  	_, errRsp = procGetEndpoint(c, vars, nil)
   342  	if errRsp == &successResponse {
   343  		t.Fatalf("Expected failure but succeeded: %v", errRsp)
   344  	}
   345  	if errRsp.StatusCode != http.StatusBadRequest {
   346  		t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode)
   347  	}
   348  
   349  	// nw by name and ep by id
   350  	vars[urlNwName] = "sh"
   351  	i1, errRsp := procGetEndpoint(c, vars, nil)
   352  	if errRsp != &successResponse {
   353  		t.Fatalf("Unexepected failure: %v", errRsp)
   354  	}
   355  	// nw by name and ep by name
   356  	delete(vars, urlEpID)
   357  	vars[urlEpName] = "ep1"
   358  	i2, errRsp := procGetEndpoint(c, vars, nil)
   359  	if errRsp != &successResponse {
   360  		t.Fatalf("Unexepected failure: %v", errRsp)
   361  	}
   362  	// nw by id and ep by name
   363  	delete(vars, urlNwName)
   364  	vars[urlNwID] = nid
   365  	i3, errRsp := procGetEndpoint(c, vars, nil)
   366  	if errRsp != &successResponse {
   367  		t.Fatalf("Unexepected failure: %v", errRsp)
   368  	}
   369  	// nw by id and ep by id
   370  	delete(vars, urlEpName)
   371  	vars[urlEpID] = eid1
   372  	i4, errRsp := procGetEndpoint(c, vars, nil)
   373  	if errRsp != &successResponse {
   374  		t.Fatalf("Unexepected failure: %v", errRsp)
   375  	}
   376  
   377  	id1 := i2e(i1).ID
   378  	if id1 != i2e(i2).ID || id1 != i2e(i3).ID || id1 != i2e(i4).ID {
   379  		t.Fatalf("Endpoints retireved via different query parameters differ: %v, %v, %v, %v", i1, i2, i3, i4)
   380  	}
   381  
   382  	vars[urlNwName] = ""
   383  	_, errRsp = procGetEndpoints(c, vars, nil)
   384  	if errRsp == &successResponse {
   385  		t.Fatalf("Expected failure, got: %v", errRsp)
   386  	}
   387  
   388  	delete(vars, urlNwName)
   389  	vars[urlNwID] = "fakeID"
   390  	_, errRsp = procGetEndpoints(c, vars, nil)
   391  	if errRsp == &successResponse {
   392  		t.Fatalf("Expected failure, got: %v", errRsp)
   393  	}
   394  
   395  	vars[urlNwID] = nid
   396  	_, errRsp = procGetEndpoints(c, vars, nil)
   397  	if errRsp != &successResponse {
   398  		t.Fatalf("Unexepected failure: %v", errRsp)
   399  	}
   400  
   401  	vars[urlNwName] = "sh"
   402  	iepList, errRsp := procGetEndpoints(c, vars, nil)
   403  	if errRsp != &successResponse {
   404  		t.Fatalf("Unexepected failure: %v", errRsp)
   405  	}
   406  	epList := i2eL(iepList)
   407  	if len(epList) != 2 {
   408  		t.Fatalf("Did not return the expected number (2) of endpoint resources: %d", len(epList))
   409  	}
   410  	if "sh" != epList[0].Network || "sh" != epList[1].Network {
   411  		t.Fatalf("Did not find expected network name in endpoint resources")
   412  	}
   413  
   414  	vars = make(map[string]string)
   415  	vars[urlNwName] = ""
   416  	_, errRsp = procGetNetwork(c, vars, nil)
   417  	if errRsp == &successResponse {
   418  		t.Fatalf("Exepected failure, got: %v", errRsp)
   419  	}
   420  	vars[urlNwName] = "shhhhh"
   421  	_, errRsp = procGetNetwork(c, vars, nil)
   422  	if errRsp == &successResponse {
   423  		t.Fatalf("Exepected failure, got: %v", errRsp)
   424  	}
   425  	vars[urlNwName] = "sh"
   426  	inr1, errRsp := procGetNetwork(c, vars, nil)
   427  	if errRsp != &successResponse {
   428  		t.Fatalf("Unexepected failure: %v", errRsp)
   429  	}
   430  	nr1 := i2n(inr1)
   431  
   432  	delete(vars, urlNwName)
   433  	vars[urlNwID] = "acacac"
   434  	_, errRsp = procGetNetwork(c, vars, nil)
   435  	if errRsp == &successResponse {
   436  		t.Fatalf("Expected failure. Got: %v", errRsp)
   437  	}
   438  	vars[urlNwID] = nid
   439  	inr2, errRsp := procGetNetwork(c, vars, nil)
   440  	if errRsp != &successResponse {
   441  		t.Fatalf("procgetNetworkByName() != procgetNetworkById(), %v vs %v", inr1, inr2)
   442  	}
   443  	nr2 := i2n(inr2)
   444  	if nr1.Name != nr2.Name || nr1.Type != nr2.Type || nr1.ID != nr2.ID || len(nr1.Endpoints) != len(nr2.Endpoints) {
   445  		t.Fatalf("Get by name and Get failure: %v", errRsp)
   446  	}
   447  
   448  	if len(nr1.Endpoints) != 2 {
   449  		t.Fatalf("Did not find the expected number (2) of endpoint resources in the network resource: %d", len(nr1.Endpoints))
   450  	}
   451  	for _, er := range nr1.Endpoints {
   452  		if er.ID != eid1 && er.ID != eid2 {
   453  			t.Fatalf("Did not find the expected endpoint resources in the network resource: %v", nr1.Endpoints)
   454  		}
   455  	}
   456  
   457  	iList, errRsp := procGetNetworks(c, nil, nil)
   458  	if errRsp != &successResponse {
   459  		t.Fatalf("Unexepected failure: %v", errRsp)
   460  	}
   461  	netList := i2nL(iList)
   462  	if len(netList) != 1 {
   463  		t.Fatalf("Did not return the expected number of network resources")
   464  	}
   465  	if nid != netList[0].ID {
   466  		t.Fatalf("Did not find expected network %s: %v", nid, netList)
   467  	}
   468  
   469  	_, errRsp = procDeleteNetwork(c, vars, nil)
   470  	if errRsp == &successResponse {
   471  		t.Fatalf("Exepected failure, got: %v", errRsp)
   472  	}
   473  
   474  	vars[urlEpName] = "ep1"
   475  	_, errRsp = procDeleteEndpoint(c, vars, nil)
   476  	if errRsp != &successResponse {
   477  		t.Fatalf("Unexepected failure: %v", errRsp)
   478  	}
   479  	delete(vars, urlEpName)
   480  	iepList, errRsp = procGetEndpoints(c, vars, nil)
   481  	if errRsp != &successResponse {
   482  		t.Fatalf("Unexepected failure: %v", errRsp)
   483  	}
   484  	epList = i2eL(iepList)
   485  	if len(epList) != 1 {
   486  		t.Fatalf("Did not return the expected number (1) of endpoint resources: %d", len(epList))
   487  	}
   488  
   489  	vars[urlEpName] = "ep2"
   490  	_, errRsp = procDeleteEndpoint(c, vars, nil)
   491  	if errRsp != &successResponse {
   492  		t.Fatalf("Unexepected failure: %v", errRsp)
   493  	}
   494  	iepList, errRsp = procGetEndpoints(c, vars, nil)
   495  	if errRsp != &successResponse {
   496  		t.Fatalf("Unexepected failure: %v", errRsp)
   497  	}
   498  	epList = i2eL(iepList)
   499  	if len(epList) != 0 {
   500  		t.Fatalf("Did not return the expected number (0) of endpoint resources: %d", len(epList))
   501  	}
   502  
   503  	_, errRsp = procDeleteNetwork(c, vars, nil)
   504  	if errRsp != &successResponse {
   505  		t.Fatalf("Unexepected failure: %v", errRsp)
   506  	}
   507  
   508  	iList, errRsp = procGetNetworks(c, nil, nil)
   509  	if errRsp != &successResponse {
   510  		t.Fatalf("Unexepected failure: %v", errRsp)
   511  	}
   512  	netList = i2nL(iList)
   513  	if len(netList) != 0 {
   514  		t.Fatalf("Did not return the expected number of network resources")
   515  	}
   516  }
   517  
   518  func TestProcGetServices(t *testing.T) {
   519  	defer testutils.SetupTestOSContext(t)()
   520  
   521  	// Cleanup local datastore file
   522  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
   523  
   524  	c, err := libnetwork.New()
   525  	if err != nil {
   526  		t.Fatal(err)
   527  	}
   528  	defer c.Stop()
   529  
   530  	// Create 2 networks
   531  	netName1 := "production"
   532  	netOption := options.Generic{
   533  		netlabel.GenericData: options.Generic{
   534  			"BridgeName": netName1,
   535  		},
   536  	}
   537  	nw1, err := c.NewNetwork(bridgeNetType, netName1, "", libnetwork.NetworkOptionGeneric(netOption))
   538  	if err != nil {
   539  		t.Fatal(err)
   540  	}
   541  
   542  	netName2 := "workdev"
   543  	netOption = options.Generic{
   544  		netlabel.GenericData: options.Generic{
   545  			"BridgeName": netName2,
   546  		},
   547  	}
   548  	nw2, err := c.NewNetwork(bridgeNetType, netName2, "", libnetwork.NetworkOptionGeneric(netOption))
   549  	if err != nil {
   550  		t.Fatal(err)
   551  	}
   552  
   553  	vars := make(map[string]string)
   554  	li, errRsp := procGetServices(c, vars, nil)
   555  	if !errRsp.isOK() {
   556  		t.Fatalf("Unexpected failure: %v", errRsp)
   557  	}
   558  	list := i2eL(li)
   559  	if len(list) != 0 {
   560  		t.Fatalf("Unexpected services in response: %v", list)
   561  	}
   562  
   563  	// Add a couple of services on one network and one on the other network
   564  	ep11, err := nw1.CreateEndpoint("db-prod")
   565  	if err != nil {
   566  		t.Fatal(err)
   567  	}
   568  	ep12, err := nw1.CreateEndpoint("web-prod")
   569  	if err != nil {
   570  		t.Fatal(err)
   571  	}
   572  	ep21, err := nw2.CreateEndpoint("db-dev")
   573  	if err != nil {
   574  		t.Fatal(err)
   575  	}
   576  
   577  	li, errRsp = procGetServices(c, vars, nil)
   578  	if !errRsp.isOK() {
   579  		t.Fatalf("Unexpected failure: %v", errRsp)
   580  	}
   581  	list = i2eL(li)
   582  	if len(list) != 3 {
   583  		t.Fatalf("Unexpected services in response: %v", list)
   584  	}
   585  
   586  	// Filter by network
   587  	vars[urlNwName] = netName1
   588  	li, errRsp = procGetServices(c, vars, nil)
   589  	if !errRsp.isOK() {
   590  		t.Fatalf("Unexpected failure: %v", errRsp)
   591  	}
   592  	list = i2eL(li)
   593  	if len(list) != 2 {
   594  		t.Fatalf("Unexpected services in response: %v", list)
   595  	}
   596  
   597  	vars[urlNwName] = netName2
   598  	li, errRsp = procGetServices(c, vars, nil)
   599  	if !errRsp.isOK() {
   600  		t.Fatalf("Unexpected failure: %v", errRsp)
   601  	}
   602  	list = i2eL(li)
   603  	if len(list) != 1 {
   604  		t.Fatalf("Unexpected services in response: %v", list)
   605  	}
   606  
   607  	vars[urlNwName] = "unknown-network"
   608  	li, errRsp = procGetServices(c, vars, nil)
   609  	if !errRsp.isOK() {
   610  		t.Fatalf("Unexpected failure: %v", errRsp)
   611  	}
   612  	list = i2eL(li)
   613  	if len(list) != 0 {
   614  		t.Fatalf("Unexpected services in response: %v", list)
   615  	}
   616  
   617  	// Query by name
   618  	delete(vars, urlNwName)
   619  	vars[urlEpName] = "db-prod"
   620  	li, errRsp = procGetServices(c, vars, nil)
   621  	if !errRsp.isOK() {
   622  		t.Fatalf("Unexpected failure: %v", errRsp)
   623  	}
   624  	list = i2eL(li)
   625  	if len(list) != 1 {
   626  		t.Fatalf("Unexpected services in response: %v", list)
   627  	}
   628  
   629  	vars[urlEpName] = "no-service"
   630  	li, errRsp = procGetServices(c, vars, nil)
   631  	if !errRsp.isOK() {
   632  		t.Fatalf("Unexpected failure: %v", errRsp)
   633  	}
   634  	list = i2eL(li)
   635  	if len(list) != 0 {
   636  		t.Fatalf("Unexpected services in response: %v", list)
   637  	}
   638  
   639  	// Query by id or partial id
   640  	delete(vars, urlEpName)
   641  	vars[urlEpPID] = ep12.ID()
   642  	li, errRsp = procGetServices(c, vars, nil)
   643  	if !errRsp.isOK() {
   644  		t.Fatalf("Unexpected failure: %v", errRsp)
   645  	}
   646  	list = i2eL(li)
   647  	if len(list) != 1 {
   648  		t.Fatalf("Unexpected services in response: %v", list)
   649  	}
   650  	if list[0].ID != ep12.ID() {
   651  		t.Fatalf("Unexpected element in response: %v", list)
   652  	}
   653  
   654  	vars[urlEpPID] = "non-id"
   655  	li, errRsp = procGetServices(c, vars, nil)
   656  	if !errRsp.isOK() {
   657  		t.Fatalf("Unexpected failure: %v", errRsp)
   658  	}
   659  	list = i2eL(li)
   660  	if len(list) != 0 {
   661  		t.Fatalf("Unexpected services in response: %v", list)
   662  	}
   663  
   664  	delete(vars, urlEpPID)
   665  	err = ep11.Delete(false)
   666  	if err != nil {
   667  		t.Fatal(err)
   668  	}
   669  	err = ep12.Delete(false)
   670  	if err != nil {
   671  		t.Fatal(err)
   672  	}
   673  	err = ep21.Delete(false)
   674  	if err != nil {
   675  		t.Fatal(err)
   676  	}
   677  
   678  	li, errRsp = procGetServices(c, vars, nil)
   679  	if !errRsp.isOK() {
   680  		t.Fatalf("Unexpected failure: %v", errRsp)
   681  	}
   682  	list = i2eL(li)
   683  	if len(list) != 0 {
   684  		t.Fatalf("Unexpected services in response: %v", list)
   685  	}
   686  }
   687  
   688  func TestProcGetService(t *testing.T) {
   689  	defer testutils.SetupTestOSContext(t)()
   690  
   691  	c, nw := createTestNetwork(t, "network")
   692  	defer c.Stop()
   693  	ep1, err := nw.CreateEndpoint("db")
   694  	if err != nil {
   695  		t.Fatal(err)
   696  	}
   697  	ep2, err := nw.CreateEndpoint("web")
   698  	if err != nil {
   699  		t.Fatal(err)
   700  	}
   701  
   702  	vars := map[string]string{urlEpID: ""}
   703  	_, errRsp := procGetService(c, vars, nil)
   704  	if errRsp.isOK() {
   705  		t.Fatalf("Expected failure, but succeeded")
   706  	}
   707  	if errRsp.StatusCode != http.StatusBadRequest {
   708  		t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode)
   709  	}
   710  
   711  	vars[urlEpID] = "unknown-service-id"
   712  	_, errRsp = procGetService(c, vars, nil)
   713  	if errRsp.isOK() {
   714  		t.Fatalf("Expected failure, but succeeded")
   715  	}
   716  	if errRsp.StatusCode != http.StatusNotFound {
   717  		t.Fatalf("Expected %d, but got: %d. (%v)", http.StatusNotFound, errRsp.StatusCode, errRsp)
   718  	}
   719  
   720  	vars[urlEpID] = ep1.ID()
   721  	si, errRsp := procGetService(c, vars, nil)
   722  	if !errRsp.isOK() {
   723  		t.Fatalf("Unexpected failure: %v", errRsp)
   724  	}
   725  	sv := i2e(si)
   726  	if sv.ID != ep1.ID() {
   727  		t.Fatalf("Unexpected service resource returned: %v", sv)
   728  	}
   729  
   730  	vars[urlEpID] = ep2.ID()
   731  	si, errRsp = procGetService(c, vars, nil)
   732  	if !errRsp.isOK() {
   733  		t.Fatalf("Unexpected failure: %v", errRsp)
   734  	}
   735  	sv = i2e(si)
   736  	if sv.ID != ep2.ID() {
   737  		t.Fatalf("Unexpected service resource returned: %v", sv)
   738  	}
   739  }
   740  
   741  func TestProcPublishUnpublishService(t *testing.T) {
   742  	defer testutils.SetupTestOSContext(t)()
   743  
   744  	c, _ := createTestNetwork(t, "network")
   745  	defer c.Stop()
   746  
   747  	vars := make(map[string]string)
   748  
   749  	vbad, err := json.Marshal("bad service create data")
   750  	if err != nil {
   751  		t.Fatal(err)
   752  	}
   753  	_, errRsp := procPublishService(c, vars, vbad)
   754  	if errRsp == &createdResponse {
   755  		t.Fatalf("Expected to fail but succeeded")
   756  	}
   757  	if errRsp.StatusCode != http.StatusBadRequest {
   758  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
   759  	}
   760  
   761  	b, err := json.Marshal(servicePublish{Name: ""})
   762  	if err != nil {
   763  		t.Fatal(err)
   764  	}
   765  	_, errRsp = procPublishService(c, vars, b)
   766  	if errRsp == &createdResponse {
   767  		t.Fatalf("Expected to fail but succeeded")
   768  	}
   769  	if errRsp.StatusCode != http.StatusBadRequest {
   770  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
   771  	}
   772  
   773  	b, err = json.Marshal(servicePublish{Name: "db"})
   774  	if err != nil {
   775  		t.Fatal(err)
   776  	}
   777  	_, errRsp = procPublishService(c, vars, b)
   778  	if errRsp == &createdResponse {
   779  		t.Fatalf("Expected to fail but succeeded")
   780  	}
   781  	if errRsp.StatusCode != http.StatusBadRequest {
   782  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
   783  	}
   784  
   785  	b, err = json.Marshal(servicePublish{Name: "db", Network: "unknown-network"})
   786  	if err != nil {
   787  		t.Fatal(err)
   788  	}
   789  	_, errRsp = procPublishService(c, vars, b)
   790  	if errRsp == &createdResponse {
   791  		t.Fatalf("Expected to fail but succeeded")
   792  	}
   793  	if errRsp.StatusCode != http.StatusNotFound {
   794  		t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp)
   795  	}
   796  
   797  	b, err = json.Marshal(servicePublish{Name: "", Network: "network"})
   798  	if err != nil {
   799  		t.Fatal(err)
   800  	}
   801  	_, errRsp = procPublishService(c, vars, b)
   802  	if errRsp == &createdResponse {
   803  		t.Fatalf("Expected to fail but succeeded")
   804  	}
   805  	if errRsp.StatusCode != http.StatusBadRequest {
   806  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
   807  	}
   808  
   809  	b, err = json.Marshal(servicePublish{Name: "db", Network: "network"})
   810  	if err != nil {
   811  		t.Fatal(err)
   812  	}
   813  	_, errRsp = procPublishService(c, vars, b)
   814  	if errRsp != &createdResponse {
   815  		t.Fatalf("Unexpected failure: %v", errRsp)
   816  	}
   817  
   818  	sp := servicePublish{
   819  		Name:    "web",
   820  		Network: "network",
   821  	}
   822  	b, err = json.Marshal(sp)
   823  	if err != nil {
   824  		t.Fatal(err)
   825  	}
   826  	si, errRsp := procPublishService(c, vars, b)
   827  	if errRsp != &createdResponse {
   828  		t.Fatalf("Unexpected failure: %v", errRsp)
   829  	}
   830  	sid := i2s(si)
   831  
   832  	vars[urlEpID] = ""
   833  	_, errRsp = procUnpublishService(c, vars, nil)
   834  	if errRsp.isOK() {
   835  		t.Fatalf("Expected failure but succeeded")
   836  	}
   837  	if errRsp.StatusCode != http.StatusBadRequest {
   838  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
   839  	}
   840  
   841  	vars[urlEpID] = "unknown-service-id"
   842  	_, errRsp = procUnpublishService(c, vars, nil)
   843  	if errRsp.isOK() {
   844  		t.Fatalf("Expected failure but succeeded")
   845  	}
   846  	if errRsp.StatusCode != http.StatusNotFound {
   847  		t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp)
   848  	}
   849  
   850  	vars[urlEpID] = sid
   851  	_, errRsp = procUnpublishService(c, vars, nil)
   852  	if !errRsp.isOK() {
   853  		t.Fatalf("Unexpected failure: %v", errRsp)
   854  	}
   855  
   856  	_, errRsp = procGetService(c, vars, nil)
   857  	if errRsp.isOK() {
   858  		t.Fatalf("Expected failure, but succeeded")
   859  	}
   860  	if errRsp.StatusCode != http.StatusNotFound {
   861  		t.Fatalf("Expected %d, but got: %d. (%v)", http.StatusNotFound, errRsp.StatusCode, errRsp)
   862  	}
   863  }
   864  
   865  func TestAttachDetachBackend(t *testing.T) {
   866  	defer testutils.SetupTestOSContext(t)()
   867  
   868  	c, nw := createTestNetwork(t, "network")
   869  	defer c.Stop()
   870  	ep1, err := nw.CreateEndpoint("db")
   871  	if err != nil {
   872  		t.Fatal(err)
   873  	}
   874  
   875  	vars := make(map[string]string)
   876  
   877  	vbad, err := json.Marshal("bad data")
   878  	if err != nil {
   879  		t.Fatal(err)
   880  	}
   881  	_, errRsp := procAttachBackend(c, vars, vbad)
   882  	if errRsp == &successResponse {
   883  		t.Fatalf("Expected failure, got: %v", errRsp)
   884  	}
   885  
   886  	vars[urlEpName] = "endpoint"
   887  	bad, err := json.Marshal(endpointJoin{})
   888  	if err != nil {
   889  		t.Fatal(err)
   890  	}
   891  	_, errRsp = procAttachBackend(c, vars, bad)
   892  	if errRsp == &successResponse {
   893  		t.Fatalf("Expected failure, got: %v", errRsp)
   894  	}
   895  	if errRsp.StatusCode != http.StatusNotFound {
   896  		t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp)
   897  	}
   898  
   899  	vars[urlEpID] = "db"
   900  	_, errRsp = procGetSandbox(c, vars, nil)
   901  	if errRsp.isOK() {
   902  		t.Fatalf("Expected failure. Got %v", errRsp)
   903  	}
   904  	if errRsp.StatusCode != http.StatusNotFound {
   905  		t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp)
   906  	}
   907  
   908  	vars[urlEpName] = "db"
   909  	_, errRsp = procAttachBackend(c, vars, bad)
   910  	if errRsp == &successResponse {
   911  		t.Fatalf("Expected failure, got: %v", errRsp)
   912  	}
   913  	if errRsp.StatusCode != http.StatusBadRequest {
   914  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
   915  	}
   916  
   917  	cid := "abcdefghi"
   918  	sbox, err := c.NewSandbox(cid)
   919  	sid := sbox.ID()
   920  	defer sbox.Delete()
   921  
   922  	jl := endpointJoin{SandboxID: sid}
   923  	jlb, err := json.Marshal(jl)
   924  	if err != nil {
   925  		t.Fatal(err)
   926  	}
   927  
   928  	_, errRsp = procAttachBackend(c, vars, jlb)
   929  	if errRsp != &successResponse {
   930  		t.Fatalf("Unexpected failure, got: %v", errRsp)
   931  	}
   932  
   933  	sli, errRsp := procGetSandboxes(c, vars, nil)
   934  	if errRsp != &successResponse {
   935  		t.Fatalf("Unexpected failure, got: %v", errRsp)
   936  	}
   937  	sl := i2sbL(sli)
   938  	if len(sl) != 1 {
   939  		t.Fatalf("Did not find expected number of sandboxes attached to the service: %d", len(sl))
   940  	}
   941  	if sl[0].ContainerID != cid {
   942  		t.Fatalf("Did not find expected sandbox attached to the service: %v", sl[0])
   943  	}
   944  
   945  	_, errRsp = procUnpublishService(c, vars, nil)
   946  	if errRsp.isOK() {
   947  		t.Fatalf("Expected failure but succeeded")
   948  	}
   949  	if errRsp.StatusCode != http.StatusForbidden {
   950  		t.Fatalf("Expected %d. Got: %v", http.StatusForbidden, errRsp)
   951  	}
   952  
   953  	vars[urlEpName] = "endpoint"
   954  	_, errRsp = procDetachBackend(c, vars, nil)
   955  	if errRsp == &successResponse {
   956  		t.Fatalf("Expected failure, got: %v", errRsp)
   957  	}
   958  	if errRsp.StatusCode != http.StatusNotFound {
   959  		t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp)
   960  	}
   961  
   962  	vars[urlEpName] = "db"
   963  	_, errRsp = procDetachBackend(c, vars, nil)
   964  	if errRsp == &successResponse {
   965  		t.Fatalf("Expected failure, got: %v", errRsp)
   966  	}
   967  	if errRsp.StatusCode != http.StatusBadRequest {
   968  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
   969  	}
   970  
   971  	vars[urlSbID] = sid
   972  	_, errRsp = procDetachBackend(c, vars, nil)
   973  	if errRsp != &successResponse {
   974  		t.Fatalf("Unexpected failure, got: %v", errRsp)
   975  	}
   976  
   977  	delete(vars, urlEpID)
   978  	si, errRsp := procGetSandbox(c, vars, nil)
   979  	if errRsp != &successResponse {
   980  		t.Fatalf("Unexpected failure, got: %v", errRsp)
   981  	}
   982  	sb := i2sb(si)
   983  	if sb.ContainerID != cid {
   984  		t.Fatalf("Did not find expected sandbox. Got %v", sb)
   985  	}
   986  
   987  	err = ep1.Delete(false)
   988  	if err != nil {
   989  		t.Fatal(err)
   990  	}
   991  }
   992  
   993  func TestDetectGetNetworksInvalidQueryComposition(t *testing.T) {
   994  	// Cleanup local datastore file
   995  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
   996  
   997  	c, err := libnetwork.New()
   998  	if err != nil {
   999  		t.Fatal(err)
  1000  	}
  1001  	defer c.Stop()
  1002  
  1003  	vars := map[string]string{urlNwName: "x", urlNwPID: "y"}
  1004  	_, errRsp := procGetNetworks(c, vars, nil)
  1005  	if errRsp.StatusCode != http.StatusBadRequest {
  1006  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
  1007  	}
  1008  }
  1009  
  1010  func TestDetectGetEndpointsInvalidQueryComposition(t *testing.T) {
  1011  	defer testutils.SetupTestOSContext(t)()
  1012  
  1013  	c, _ := createTestNetwork(t, "network")
  1014  	defer c.Stop()
  1015  
  1016  	vars := map[string]string{urlNwName: "network", urlEpName: "x", urlEpPID: "y"}
  1017  	_, errRsp := procGetEndpoints(c, vars, nil)
  1018  	if errRsp.StatusCode != http.StatusBadRequest {
  1019  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
  1020  	}
  1021  }
  1022  
  1023  func TestDetectGetServicesInvalidQueryComposition(t *testing.T) {
  1024  	defer testutils.SetupTestOSContext(t)()
  1025  
  1026  	c, _ := createTestNetwork(t, "network")
  1027  	defer c.Stop()
  1028  
  1029  	vars := map[string]string{urlNwName: "network", urlEpName: "x", urlEpPID: "y"}
  1030  	_, errRsp := procGetServices(c, vars, nil)
  1031  	if errRsp.StatusCode != http.StatusBadRequest {
  1032  		t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp)
  1033  	}
  1034  }
  1035  
  1036  func TestFindNetworkUtilPanic(t *testing.T) {
  1037  	defer checkPanic(t)
  1038  	findNetwork(nil, "", -1)
  1039  }
  1040  
  1041  func TestFindNetworkUtil(t *testing.T) {
  1042  	defer testutils.SetupTestOSContext(t)()
  1043  
  1044  	c, nw := createTestNetwork(t, "network")
  1045  	defer c.Stop()
  1046  
  1047  	nid := nw.ID()
  1048  
  1049  	_, errRsp := findNetwork(c, "", byName)
  1050  	if errRsp == &successResponse {
  1051  		t.Fatalf("Expected to fail but succeeded")
  1052  	}
  1053  	if errRsp.StatusCode != http.StatusBadRequest {
  1054  		t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode)
  1055  	}
  1056  
  1057  	n, errRsp := findNetwork(c, nid, byID)
  1058  	if errRsp != &successResponse {
  1059  		t.Fatalf("Unexpected failure: %v", errRsp)
  1060  	}
  1061  	if n == nil {
  1062  		t.Fatalf("Unexpected nil libnetwork.Network")
  1063  	}
  1064  	if nid != n.ID() {
  1065  		t.Fatalf("Incorrect libnetwork.Network resource. It has different id: %v", n)
  1066  	}
  1067  	if "network" != n.Name() {
  1068  		t.Fatalf("Incorrect libnetwork.Network resource. It has different name: %v", n)
  1069  	}
  1070  
  1071  	n, errRsp = findNetwork(c, "network", byName)
  1072  	if errRsp != &successResponse {
  1073  		t.Fatalf("Unexpected failure: %v", errRsp)
  1074  	}
  1075  	if n == nil {
  1076  		t.Fatalf("Unexpected nil libnetwork.Network")
  1077  	}
  1078  	if nid != n.ID() {
  1079  		t.Fatalf("Incorrect libnetwork.Network resource. It has different id: %v", n)
  1080  	}
  1081  	if "network" != n.Name() {
  1082  		t.Fatalf("Incorrect libnetwork.Network resource. It has different name: %v", n)
  1083  	}
  1084  
  1085  	if err := n.Delete(); err != nil {
  1086  		t.Fatalf("Failed to delete the network: %s", err.Error())
  1087  	}
  1088  
  1089  	_, errRsp = findNetwork(c, nid, byID)
  1090  	if errRsp == &successResponse {
  1091  		t.Fatalf("Expected to fail but succeeded")
  1092  	}
  1093  	if errRsp.StatusCode != http.StatusNotFound {
  1094  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1095  	}
  1096  
  1097  	_, errRsp = findNetwork(c, "network", byName)
  1098  	if errRsp == &successResponse {
  1099  		t.Fatalf("Expected to fail but succeeded")
  1100  	}
  1101  	if errRsp.StatusCode != http.StatusNotFound {
  1102  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1103  	}
  1104  }
  1105  
  1106  func TestCreateDeleteEndpoints(t *testing.T) {
  1107  	defer testutils.SetupTestOSContext(t)()
  1108  
  1109  	// Cleanup local datastore file
  1110  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
  1111  
  1112  	c, err := libnetwork.New()
  1113  	if err != nil {
  1114  		t.Fatal(err)
  1115  	}
  1116  	defer c.Stop()
  1117  
  1118  	nc := networkCreate{Name: "firstNet", NetworkType: bridgeNetType}
  1119  	body, err := json.Marshal(nc)
  1120  	if err != nil {
  1121  		t.Fatal(err)
  1122  	}
  1123  
  1124  	vars := make(map[string]string)
  1125  	i, errRsp := procCreateNetwork(c, vars, body)
  1126  	if errRsp != &createdResponse {
  1127  		t.Fatalf("Unexepected failure: %v", errRsp)
  1128  	}
  1129  	nid := i2s(i)
  1130  
  1131  	vbad, err := json.Marshal("bad endppoint create data")
  1132  	if err != nil {
  1133  		t.Fatal(err)
  1134  	}
  1135  
  1136  	vars[urlNwName] = "firstNet"
  1137  	_, errRsp = procCreateEndpoint(c, vars, vbad)
  1138  	if errRsp == &createdResponse {
  1139  		t.Fatalf("Expected to fail but succeeded")
  1140  	}
  1141  
  1142  	b, err := json.Marshal(endpointCreate{Name: ""})
  1143  	if err != nil {
  1144  		t.Fatal(err)
  1145  	}
  1146  
  1147  	vars[urlNwName] = "secondNet"
  1148  	_, errRsp = procCreateEndpoint(c, vars, b)
  1149  	if errRsp == &createdResponse {
  1150  		t.Fatalf("Expected to fail but succeeded")
  1151  	}
  1152  
  1153  	vars[urlNwName] = "firstNet"
  1154  	_, errRsp = procCreateEndpoint(c, vars, b)
  1155  	if errRsp == &successResponse {
  1156  		t.Fatalf("Expected failure but succeeded: %v", errRsp)
  1157  	}
  1158  
  1159  	b, err = json.Marshal(endpointCreate{Name: "firstEp"})
  1160  	if err != nil {
  1161  		t.Fatal(err)
  1162  	}
  1163  
  1164  	i, errRsp = procCreateEndpoint(c, vars, b)
  1165  	if errRsp != &createdResponse {
  1166  		t.Fatalf("Unexepected failure: %v", errRsp)
  1167  	}
  1168  	eid := i2s(i)
  1169  
  1170  	_, errRsp = findEndpoint(c, "myNet", "firstEp", byName, byName)
  1171  	if errRsp == &successResponse {
  1172  		t.Fatalf("Expected failure but succeeded: %v", errRsp)
  1173  	}
  1174  
  1175  	ep0, errRsp := findEndpoint(c, nid, "firstEp", byID, byName)
  1176  	if errRsp != &successResponse {
  1177  		t.Fatalf("Unexepected failure: %v", errRsp)
  1178  	}
  1179  
  1180  	ep1, errRsp := findEndpoint(c, "firstNet", "firstEp", byName, byName)
  1181  	if errRsp != &successResponse {
  1182  		t.Fatalf("Unexepected failure: %v", errRsp)
  1183  	}
  1184  
  1185  	ep2, errRsp := findEndpoint(c, nid, eid, byID, byID)
  1186  	if errRsp != &successResponse {
  1187  		t.Fatalf("Unexepected failure: %v", errRsp)
  1188  	}
  1189  
  1190  	ep3, errRsp := findEndpoint(c, "firstNet", eid, byName, byID)
  1191  	if errRsp != &successResponse {
  1192  		t.Fatalf("Unexepected failure: %v", errRsp)
  1193  	}
  1194  
  1195  	if ep0.ID() != ep1.ID() || ep0.ID() != ep2.ID() || ep0.ID() != ep3.ID() {
  1196  		t.Fatalf("Diffenrent queries returned different endpoints: \nep0: %v\nep1: %v\nep2: %v\nep3: %v", ep0, ep1, ep2, ep3)
  1197  	}
  1198  
  1199  	vars = make(map[string]string)
  1200  	vars[urlNwName] = ""
  1201  	vars[urlEpName] = "ep1"
  1202  	_, errRsp = procDeleteEndpoint(c, vars, nil)
  1203  	if errRsp == &successResponse {
  1204  		t.Fatalf("Expected failure, got: %v", errRsp)
  1205  	}
  1206  
  1207  	vars[urlNwName] = "firstNet"
  1208  	vars[urlEpName] = ""
  1209  	_, errRsp = procDeleteEndpoint(c, vars, nil)
  1210  	if errRsp == &successResponse {
  1211  		t.Fatalf("Expected failure, got: %v", errRsp)
  1212  	}
  1213  
  1214  	vars[urlEpName] = "ep2"
  1215  	_, errRsp = procDeleteEndpoint(c, vars, nil)
  1216  	if errRsp == &successResponse {
  1217  		t.Fatalf("Expected failure, got: %v", errRsp)
  1218  	}
  1219  
  1220  	vars[urlEpName] = "firstEp"
  1221  	_, errRsp = procDeleteEndpoint(c, vars, nil)
  1222  	if errRsp != &successResponse {
  1223  		t.Fatalf("Unexepected failure: %v", errRsp)
  1224  	}
  1225  
  1226  	_, errRsp = findEndpoint(c, "firstNet", "firstEp", byName, byName)
  1227  	if errRsp == &successResponse {
  1228  		t.Fatalf("Expected failure, got: %v", errRsp)
  1229  	}
  1230  }
  1231  
  1232  func TestJoinLeave(t *testing.T) {
  1233  	defer testutils.SetupTestOSContext(t)()
  1234  
  1235  	// Cleanup local datastore file
  1236  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
  1237  
  1238  	c, err := libnetwork.New()
  1239  	if err != nil {
  1240  		t.Fatal(err)
  1241  	}
  1242  	defer c.Stop()
  1243  
  1244  	nb, err := json.Marshal(networkCreate{Name: "network", NetworkType: bridgeNetType})
  1245  	if err != nil {
  1246  		t.Fatal(err)
  1247  	}
  1248  	vars := make(map[string]string)
  1249  	_, errRsp := procCreateNetwork(c, vars, nb)
  1250  	if errRsp != &createdResponse {
  1251  		t.Fatalf("Unexepected failure: %v", errRsp)
  1252  	}
  1253  
  1254  	eb, err := json.Marshal(endpointCreate{Name: "endpoint"})
  1255  	if err != nil {
  1256  		t.Fatal(err)
  1257  	}
  1258  	vars[urlNwName] = "network"
  1259  	_, errRsp = procCreateEndpoint(c, vars, eb)
  1260  	if errRsp != &createdResponse {
  1261  		t.Fatalf("Unexepected failure: %v", errRsp)
  1262  	}
  1263  
  1264  	vbad, err := json.Marshal("bad data")
  1265  	if err != nil {
  1266  		t.Fatal(err)
  1267  	}
  1268  	_, errRsp = procJoinEndpoint(c, vars, vbad)
  1269  	if errRsp == &successResponse {
  1270  		t.Fatalf("Expected failure, got: %v", errRsp)
  1271  	}
  1272  
  1273  	vars[urlEpName] = "endpoint"
  1274  	bad, err := json.Marshal(endpointJoin{})
  1275  	if err != nil {
  1276  		t.Fatal(err)
  1277  	}
  1278  	_, errRsp = procJoinEndpoint(c, vars, bad)
  1279  	if errRsp == &successResponse {
  1280  		t.Fatalf("Expected failure, got: %v", errRsp)
  1281  	}
  1282  
  1283  	cid := "abcdefghi"
  1284  	sb, err := c.NewSandbox(cid)
  1285  	defer sb.Delete()
  1286  
  1287  	jl := endpointJoin{SandboxID: sb.ID()}
  1288  	jlb, err := json.Marshal(jl)
  1289  	if err != nil {
  1290  		t.Fatal(err)
  1291  	}
  1292  
  1293  	vars = make(map[string]string)
  1294  	vars[urlNwName] = ""
  1295  	vars[urlEpName] = ""
  1296  	_, errRsp = procJoinEndpoint(c, vars, jlb)
  1297  	if errRsp == &successResponse {
  1298  		t.Fatalf("Expected failure, got: %v", errRsp)
  1299  	}
  1300  
  1301  	vars[urlNwName] = "network"
  1302  	vars[urlEpName] = ""
  1303  	_, errRsp = procJoinEndpoint(c, vars, jlb)
  1304  	if errRsp == &successResponse {
  1305  		t.Fatalf("Expected failure, got: %v", errRsp)
  1306  	}
  1307  
  1308  	vars[urlEpName] = "epoint"
  1309  	_, errRsp = procJoinEndpoint(c, vars, jlb)
  1310  	if errRsp == &successResponse {
  1311  		t.Fatalf("Expected failure, got: %v", errRsp)
  1312  	}
  1313  
  1314  	// bad labels
  1315  	vars[urlEpName] = "endpoint"
  1316  	key, errRsp := procJoinEndpoint(c, vars, jlb)
  1317  	if errRsp != &successResponse {
  1318  		t.Fatalf("Unexepected failure, got: %v", errRsp)
  1319  	}
  1320  
  1321  	keyStr := i2s(key)
  1322  	if keyStr == "" {
  1323  		t.Fatalf("Empty sandbox key")
  1324  	}
  1325  	_, errRsp = procDeleteEndpoint(c, vars, nil)
  1326  	if errRsp == &successResponse {
  1327  		t.Fatalf("Expected failure, got: %v", errRsp)
  1328  	}
  1329  
  1330  	vars[urlNwName] = "network2"
  1331  	_, errRsp = procLeaveEndpoint(c, vars, vbad)
  1332  	if errRsp == &successResponse {
  1333  		t.Fatalf("Expected failure, got: %v", errRsp)
  1334  	}
  1335  	_, errRsp = procLeaveEndpoint(c, vars, bad)
  1336  	if errRsp == &successResponse {
  1337  		t.Fatalf("Expected failure, got: %v", errRsp)
  1338  	}
  1339  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1340  	if errRsp == &successResponse {
  1341  		t.Fatalf("Expected failure, got: %v", errRsp)
  1342  	}
  1343  	vars = make(map[string]string)
  1344  	vars[urlNwName] = ""
  1345  	vars[urlEpName] = ""
  1346  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1347  	if errRsp == &successResponse {
  1348  		t.Fatalf("Expected failure, got: %v", errRsp)
  1349  	}
  1350  	vars[urlNwName] = "network"
  1351  	vars[urlEpName] = ""
  1352  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1353  	if errRsp == &successResponse {
  1354  		t.Fatalf("Expected failure, got: %v", errRsp)
  1355  	}
  1356  	vars[urlEpName] = "2epoint"
  1357  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1358  	if errRsp == &successResponse {
  1359  		t.Fatalf("Expected failure, got: %v", errRsp)
  1360  	}
  1361  	vars[urlEpName] = "epoint"
  1362  	vars[urlCnID] = "who"
  1363  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1364  	if errRsp == &successResponse {
  1365  		t.Fatalf("Expected failure, got: %v", errRsp)
  1366  	}
  1367  
  1368  	delete(vars, urlCnID)
  1369  	vars[urlEpName] = "endpoint"
  1370  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1371  	if errRsp == &successResponse {
  1372  		t.Fatalf("Expected failure, got: %v", errRsp)
  1373  	}
  1374  
  1375  	vars[urlSbID] = sb.ID()
  1376  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1377  	if errRsp != &successResponse {
  1378  		t.Fatalf("Unexepected failure: %v", errRsp)
  1379  	}
  1380  
  1381  	_, errRsp = procLeaveEndpoint(c, vars, jlb)
  1382  	if errRsp == &successResponse {
  1383  		t.Fatalf("Expected failure, got: %v", errRsp)
  1384  	}
  1385  
  1386  	_, errRsp = procDeleteEndpoint(c, vars, nil)
  1387  	if errRsp != &successResponse {
  1388  		t.Fatalf("Unexepected failure: %v", errRsp)
  1389  	}
  1390  }
  1391  
  1392  func TestFindEndpointUtilPanic(t *testing.T) {
  1393  	defer testutils.SetupTestOSContext(t)()
  1394  	defer checkPanic(t)
  1395  	c, nw := createTestNetwork(t, "network")
  1396  	defer c.Stop()
  1397  
  1398  	nid := nw.ID()
  1399  	findEndpoint(c, nid, "", byID, -1)
  1400  }
  1401  
  1402  func TestFindServiceUtilPanic(t *testing.T) {
  1403  	defer testutils.SetupTestOSContext(t)()
  1404  	defer checkPanic(t)
  1405  	c, _ := createTestNetwork(t, "network")
  1406  	defer c.Stop()
  1407  
  1408  	findService(c, "random_service", -1)
  1409  }
  1410  
  1411  func TestFindEndpointUtil(t *testing.T) {
  1412  	defer testutils.SetupTestOSContext(t)()
  1413  
  1414  	c, nw := createTestNetwork(t, "network")
  1415  	defer c.Stop()
  1416  
  1417  	nid := nw.ID()
  1418  
  1419  	ep, err := nw.CreateEndpoint("secondEp", nil)
  1420  	if err != nil {
  1421  		t.Fatal(err)
  1422  	}
  1423  	eid := ep.ID()
  1424  
  1425  	_, errRsp := findEndpoint(c, nid, "", byID, byName)
  1426  	if errRsp == &successResponse {
  1427  		t.Fatalf("Expected failure, but got: %v", errRsp)
  1428  	}
  1429  	if errRsp.StatusCode != http.StatusBadRequest {
  1430  		t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode)
  1431  	}
  1432  
  1433  	ep0, errRsp := findEndpoint(c, nid, "secondEp", byID, byName)
  1434  	if errRsp != &successResponse {
  1435  		t.Fatalf("Unexepected failure: %v", errRsp)
  1436  	}
  1437  
  1438  	ep1, errRsp := findEndpoint(c, "network", "secondEp", byName, byName)
  1439  	if errRsp != &successResponse {
  1440  		t.Fatalf("Unexepected failure: %v", errRsp)
  1441  	}
  1442  
  1443  	ep2, errRsp := findEndpoint(c, nid, eid, byID, byID)
  1444  	if errRsp != &successResponse {
  1445  		t.Fatalf("Unexepected failure: %v", errRsp)
  1446  	}
  1447  
  1448  	ep3, errRsp := findEndpoint(c, "network", eid, byName, byID)
  1449  	if errRsp != &successResponse {
  1450  		t.Fatalf("Unexepected failure: %v", errRsp)
  1451  	}
  1452  
  1453  	ep4, errRsp := findService(c, "secondEp", byName)
  1454  	if errRsp != &successResponse {
  1455  		t.Fatalf("Unexepected failure: %v", errRsp)
  1456  	}
  1457  
  1458  	ep5, errRsp := findService(c, eid, byID)
  1459  	if errRsp != &successResponse {
  1460  		t.Fatalf("Unexepected failure: %v", errRsp)
  1461  	}
  1462  
  1463  	if ep0.ID() != ep1.ID() || ep0.ID() != ep2.ID() ||
  1464  		ep0.ID() != ep3.ID() || ep0.ID() != ep4.ID() || ep0.ID() != ep5.ID() {
  1465  		t.Fatalf("Diffenrent queries returned different endpoints")
  1466  	}
  1467  
  1468  	ep.Delete(false)
  1469  
  1470  	_, errRsp = findEndpoint(c, nid, "secondEp", byID, byName)
  1471  	if errRsp == &successResponse {
  1472  		t.Fatalf("Expected failure, but got: %v", errRsp)
  1473  	}
  1474  	if errRsp.StatusCode != http.StatusNotFound {
  1475  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1476  	}
  1477  
  1478  	_, errRsp = findEndpoint(c, "network", "secondEp", byName, byName)
  1479  	if errRsp == &successResponse {
  1480  		t.Fatalf("Expected failure, but got: %v", errRsp)
  1481  	}
  1482  	if errRsp.StatusCode != http.StatusNotFound {
  1483  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1484  	}
  1485  
  1486  	_, errRsp = findEndpoint(c, nid, eid, byID, byID)
  1487  	if errRsp == &successResponse {
  1488  		t.Fatalf("Expected failure, but got: %v", errRsp)
  1489  	}
  1490  	if errRsp.StatusCode != http.StatusNotFound {
  1491  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1492  	}
  1493  
  1494  	_, errRsp = findEndpoint(c, "network", eid, byName, byID)
  1495  	if errRsp == &successResponse {
  1496  		t.Fatalf("Expected failure, but got: %v", errRsp)
  1497  	}
  1498  	if errRsp.StatusCode != http.StatusNotFound {
  1499  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1500  	}
  1501  
  1502  	_, errRsp = findService(c, "secondEp", byName)
  1503  	if errRsp == &successResponse {
  1504  		t.Fatalf("Expected failure, but got: %v", errRsp)
  1505  	}
  1506  	if errRsp.StatusCode != http.StatusNotFound {
  1507  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1508  	}
  1509  
  1510  	_, errRsp = findService(c, eid, byID)
  1511  	if errRsp == &successResponse {
  1512  		t.Fatalf("Expected failure, but got: %v", errRsp)
  1513  	}
  1514  	if errRsp.StatusCode != http.StatusNotFound {
  1515  		t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode)
  1516  	}
  1517  }
  1518  
  1519  func TestEndpointToService(t *testing.T) {
  1520  	r := &responseStatus{Status: "this is one endpoint", StatusCode: http.StatusOK}
  1521  	r = endpointToService(r)
  1522  	if r.Status != "this is one service" {
  1523  		t.Fatalf("endpointToService returned unexpected status string: %s", r.Status)
  1524  	}
  1525  
  1526  	r = &responseStatus{Status: "this is one network", StatusCode: http.StatusOK}
  1527  	r = endpointToService(r)
  1528  	if r.Status != "this is one network" {
  1529  		t.Fatalf("endpointToService returned unexpected status string: %s", r.Status)
  1530  	}
  1531  }
  1532  
  1533  func checkPanic(t *testing.T) {
  1534  	if r := recover(); r != nil {
  1535  		if _, ok := r.(runtime.Error); ok {
  1536  			panic(r)
  1537  		}
  1538  	} else {
  1539  		t.Fatalf("Expected to panic, but succeeded")
  1540  	}
  1541  }
  1542  
  1543  func TestDetectNetworkTargetPanic(t *testing.T) {
  1544  	defer checkPanic(t)
  1545  	vars := make(map[string]string)
  1546  	detectNetworkTarget(vars)
  1547  }
  1548  
  1549  func TestDetectEndpointTargetPanic(t *testing.T) {
  1550  	defer checkPanic(t)
  1551  	vars := make(map[string]string)
  1552  	detectEndpointTarget(vars)
  1553  }
  1554  
  1555  func TestResponseStatus(t *testing.T) {
  1556  	list := []int{
  1557  		http.StatusBadGateway,
  1558  		http.StatusBadRequest,
  1559  		http.StatusConflict,
  1560  		http.StatusContinue,
  1561  		http.StatusExpectationFailed,
  1562  		http.StatusForbidden,
  1563  		http.StatusFound,
  1564  		http.StatusGatewayTimeout,
  1565  		http.StatusGone,
  1566  		http.StatusHTTPVersionNotSupported,
  1567  		http.StatusInternalServerError,
  1568  		http.StatusLengthRequired,
  1569  		http.StatusMethodNotAllowed,
  1570  		http.StatusMovedPermanently,
  1571  		http.StatusMultipleChoices,
  1572  		http.StatusNoContent,
  1573  		http.StatusNonAuthoritativeInfo,
  1574  		http.StatusNotAcceptable,
  1575  		http.StatusNotFound,
  1576  		http.StatusNotModified,
  1577  		http.StatusPartialContent,
  1578  		http.StatusPaymentRequired,
  1579  		http.StatusPreconditionFailed,
  1580  		http.StatusProxyAuthRequired,
  1581  		http.StatusRequestEntityTooLarge,
  1582  		http.StatusRequestTimeout,
  1583  		http.StatusRequestURITooLong,
  1584  		http.StatusRequestedRangeNotSatisfiable,
  1585  		http.StatusResetContent,
  1586  		http.StatusServiceUnavailable,
  1587  		http.StatusSwitchingProtocols,
  1588  		http.StatusTemporaryRedirect,
  1589  		http.StatusUnauthorized,
  1590  		http.StatusUnsupportedMediaType,
  1591  		http.StatusUseProxy,
  1592  	}
  1593  	for _, c := range list {
  1594  		r := responseStatus{StatusCode: c}
  1595  		if r.isOK() {
  1596  			t.Fatalf("isOK() returned true for code% d", c)
  1597  		}
  1598  	}
  1599  
  1600  	r := responseStatus{StatusCode: http.StatusOK}
  1601  	if !r.isOK() {
  1602  		t.Fatalf("isOK() failed")
  1603  	}
  1604  
  1605  	r = responseStatus{StatusCode: http.StatusCreated}
  1606  	if !r.isOK() {
  1607  		t.Fatalf("isOK() failed")
  1608  	}
  1609  }
  1610  
  1611  // Local structs for end to end testing of api.go
  1612  type localReader struct {
  1613  	data  []byte
  1614  	beBad bool
  1615  }
  1616  
  1617  func newLocalReader(data []byte) *localReader {
  1618  	lr := &localReader{data: make([]byte, len(data))}
  1619  	copy(lr.data, data)
  1620  	return lr
  1621  }
  1622  
  1623  func (l *localReader) Read(p []byte) (n int, err error) {
  1624  	if l.beBad {
  1625  		return 0, errors.New("I am a bad reader")
  1626  	}
  1627  	if p == nil {
  1628  		return -1, fmt.Errorf("nil buffer passed")
  1629  	}
  1630  	if l.data == nil || len(l.data) == 0 {
  1631  		return 0, io.EOF
  1632  	}
  1633  	copy(p[:], l.data[:])
  1634  	return len(l.data), io.EOF
  1635  }
  1636  
  1637  type localResponseWriter struct {
  1638  	body       []byte
  1639  	statusCode int
  1640  }
  1641  
  1642  func newWriter() *localResponseWriter {
  1643  	return &localResponseWriter{}
  1644  }
  1645  
  1646  func (f *localResponseWriter) Header() http.Header {
  1647  	return make(map[string][]string, 0)
  1648  }
  1649  
  1650  func (f *localResponseWriter) Write(data []byte) (int, error) {
  1651  	if data == nil {
  1652  		return -1, fmt.Errorf("nil data passed")
  1653  	}
  1654  
  1655  	f.body = make([]byte, len(data))
  1656  	copy(f.body, data)
  1657  
  1658  	return len(f.body), nil
  1659  }
  1660  
  1661  func (f *localResponseWriter) WriteHeader(c int) {
  1662  	f.statusCode = c
  1663  }
  1664  
  1665  func testWriteJSON(t *testing.T, testCode int, testData interface{}) {
  1666  	testDataMarshalled, err := json.Marshal(testData)
  1667  	if err != nil {
  1668  		t.Fatal(err)
  1669  	}
  1670  
  1671  	rsp := newWriter()
  1672  	writeJSON(rsp, testCode, testData)
  1673  	if rsp.statusCode != testCode {
  1674  		t.Fatalf("writeJSON() failed to set the status code. Expected %d. Got %d", testCode, rsp.statusCode)
  1675  	}
  1676  	// writeJSON calls json.Encode and it appends '\n' to the result,
  1677  	// while json.Marshal not
  1678  	expected := append(testDataMarshalled, byte('\n'))
  1679  	if !bytes.Equal(expected, rsp.body) {
  1680  		t.Fatalf("writeJSON() failed to set the body. Expected %q. Got %q", expected, rsp.body)
  1681  	}
  1682  }
  1683  
  1684  func TestWriteJSON(t *testing.T) {
  1685  	testWriteJSON(t, 55, "test data as string")
  1686  	testWriteJSON(t, 55, []byte("test data as bytes"))
  1687  }
  1688  
  1689  func TestHttpHandlerUninit(t *testing.T) {
  1690  	defer testutils.SetupTestOSContext(t)()
  1691  
  1692  	// Cleanup local datastore file
  1693  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
  1694  
  1695  	c, err := libnetwork.New()
  1696  	if err != nil {
  1697  		t.Fatal(err)
  1698  	}
  1699  	defer c.Stop()
  1700  
  1701  	h := &httpHandler{c: c}
  1702  	h.initRouter()
  1703  	if h.r == nil {
  1704  		t.Fatalf("initRouter() did not initialize the router")
  1705  	}
  1706  
  1707  	rsp := newWriter()
  1708  	req, err := http.NewRequest("GET", "/v1.19/networks", nil)
  1709  	if err != nil {
  1710  		t.Fatal(err)
  1711  	}
  1712  
  1713  	handleRequest := NewHTTPHandler(nil)
  1714  	handleRequest(rsp, req)
  1715  	if rsp.statusCode != http.StatusServiceUnavailable {
  1716  		t.Fatalf("Expected (%d). Got (%d): %s", http.StatusServiceUnavailable, rsp.statusCode, rsp.body)
  1717  	}
  1718  
  1719  	handleRequest = NewHTTPHandler(c)
  1720  
  1721  	handleRequest(rsp, req)
  1722  	if rsp.statusCode != http.StatusOK {
  1723  		t.Fatalf("Expected (%d). Got: (%d): %s", http.StatusOK, rsp.statusCode, rsp.body)
  1724  	}
  1725  
  1726  	var list []*networkResource
  1727  	err = json.Unmarshal(rsp.body, &list)
  1728  	if err != nil {
  1729  		t.Fatal(err)
  1730  	}
  1731  	if len(list) != 0 {
  1732  		t.Fatalf("Expected empty list. Got %v", list)
  1733  	}
  1734  
  1735  	n, err := c.NewNetwork(bridgeNetType, "didietro", "", nil)
  1736  	if err != nil {
  1737  		t.Fatal(err)
  1738  	}
  1739  	nwr := buildNetworkResource(n)
  1740  	expected, err := json.Marshal([]*networkResource{nwr})
  1741  	if err != nil {
  1742  		t.Fatal(err)
  1743  	}
  1744  
  1745  	handleRequest(rsp, req)
  1746  	if rsp.statusCode != http.StatusOK {
  1747  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  1748  	}
  1749  	if len(rsp.body) == 0 {
  1750  		t.Fatalf("Empty list of networks")
  1751  	}
  1752  	if bytes.Equal(rsp.body, expected) {
  1753  		t.Fatalf("Incorrect list of networks in response's body")
  1754  	}
  1755  }
  1756  
  1757  func TestHttpHandlerBadBody(t *testing.T) {
  1758  	defer testutils.SetupTestOSContext(t)()
  1759  
  1760  	rsp := newWriter()
  1761  
  1762  	// Cleanup local datastore file
  1763  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
  1764  
  1765  	c, err := libnetwork.New()
  1766  	if err != nil {
  1767  		t.Fatal(err)
  1768  	}
  1769  	defer c.Stop()
  1770  	handleRequest := NewHTTPHandler(c)
  1771  
  1772  	req, err := http.NewRequest("POST", "/v1.19/networks", &localReader{beBad: true})
  1773  	if err != nil {
  1774  		t.Fatal(err)
  1775  	}
  1776  	handleRequest(rsp, req)
  1777  	if rsp.statusCode != http.StatusBadRequest {
  1778  		t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusBadRequest, rsp.statusCode, string(rsp.body))
  1779  	}
  1780  
  1781  	body := []byte{}
  1782  	lr := newLocalReader(body)
  1783  	req, err = http.NewRequest("POST", "/v1.19/networks", lr)
  1784  	if err != nil {
  1785  		t.Fatal(err)
  1786  	}
  1787  	handleRequest(rsp, req)
  1788  	if rsp.statusCode != http.StatusBadRequest {
  1789  		t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusBadRequest, rsp.statusCode, string(rsp.body))
  1790  	}
  1791  }
  1792  
  1793  func TestEndToEnd(t *testing.T) {
  1794  	defer testutils.SetupTestOSContext(t)()
  1795  
  1796  	rsp := newWriter()
  1797  
  1798  	// Cleanup local datastore file
  1799  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
  1800  
  1801  	c, err := libnetwork.New()
  1802  	if err != nil {
  1803  		t.Fatal(err)
  1804  	}
  1805  	defer c.Stop()
  1806  
  1807  	handleRequest := NewHTTPHandler(c)
  1808  
  1809  	dops := GetOpsMap("cdef", "1460")
  1810  	nops := map[string]string{
  1811  		netlabel.EnableIPv6: "true",
  1812  	}
  1813  
  1814  	// Create network
  1815  	nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops}
  1816  	body, err := json.Marshal(nc)
  1817  	if err != nil {
  1818  		t.Fatal(err)
  1819  	}
  1820  	lr := newLocalReader(body)
  1821  	req, err := http.NewRequest("POST", "/v1.19/networks", lr)
  1822  	if err != nil {
  1823  		t.Fatal(err)
  1824  	}
  1825  	handleRequest(rsp, req)
  1826  	if rsp.statusCode != http.StatusCreated {
  1827  		t.Fatalf("Unexpectded status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body))
  1828  	}
  1829  	if len(rsp.body) == 0 {
  1830  		t.Fatalf("Empty response body")
  1831  	}
  1832  
  1833  	var nid string
  1834  	err = json.Unmarshal(rsp.body, &nid)
  1835  	if err != nil {
  1836  		t.Fatal(err)
  1837  	}
  1838  
  1839  	// Query networks collection
  1840  	req, err = http.NewRequest("GET", "/v1.19/networks?name=", nil)
  1841  	if err != nil {
  1842  		t.Fatal(err)
  1843  	}
  1844  	handleRequest(rsp, req)
  1845  	if rsp.statusCode != http.StatusOK {
  1846  		t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body)
  1847  	}
  1848  	var list []*networkResource
  1849  	err = json.Unmarshal(rsp.body, &list)
  1850  	if err != nil {
  1851  		t.Fatal(err)
  1852  	}
  1853  	if len(list) != 0 {
  1854  		t.Fatalf("Expected empty list. Got %v", list)
  1855  	}
  1856  
  1857  	req, err = http.NewRequest("GET", "/v1.19/networks", nil)
  1858  	if err != nil {
  1859  		t.Fatal(err)
  1860  	}
  1861  	handleRequest(rsp, req)
  1862  	if rsp.statusCode != http.StatusOK {
  1863  		t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body)
  1864  	}
  1865  
  1866  	b0 := make([]byte, len(rsp.body))
  1867  	copy(b0, rsp.body)
  1868  
  1869  	req, err = http.NewRequest("GET", "/v1.19/networks?name=network-fiftyfive", nil)
  1870  	if err != nil {
  1871  		t.Fatal(err)
  1872  	}
  1873  	handleRequest(rsp, req)
  1874  	if rsp.statusCode != http.StatusOK {
  1875  		t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body)
  1876  	}
  1877  
  1878  	if !bytes.Equal(b0, rsp.body) {
  1879  		t.Fatalf("Expected same body from GET /networks and GET /networks?name=<nw> when only network <nw> exist.")
  1880  	}
  1881  
  1882  	// Query network by name
  1883  	req, err = http.NewRequest("GET", "/v1.19/networks?name=culo", nil)
  1884  	if err != nil {
  1885  		t.Fatal(err)
  1886  	}
  1887  	handleRequest(rsp, req)
  1888  	if rsp.statusCode != http.StatusOK {
  1889  		t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body)
  1890  	}
  1891  
  1892  	err = json.Unmarshal(rsp.body, &list)
  1893  	if err != nil {
  1894  		t.Fatal(err)
  1895  	}
  1896  	if len(list) != 0 {
  1897  		t.Fatalf("Expected empty list. Got %v", list)
  1898  	}
  1899  
  1900  	req, err = http.NewRequest("GET", "/v1.19/networks?name=network-fiftyfive", nil)
  1901  	if err != nil {
  1902  		t.Fatal(err)
  1903  	}
  1904  	handleRequest(rsp, req)
  1905  	if rsp.statusCode != http.StatusOK {
  1906  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  1907  	}
  1908  
  1909  	err = json.Unmarshal(rsp.body, &list)
  1910  	if err != nil {
  1911  		t.Fatal(err)
  1912  	}
  1913  	if len(list) == 0 {
  1914  		t.Fatalf("Expected non empty list")
  1915  	}
  1916  	if list[0].Name != "network-fiftyfive" || nid != list[0].ID {
  1917  		t.Fatalf("Incongruent resource found: %v", list[0])
  1918  	}
  1919  
  1920  	// Query network by partial id
  1921  	chars := []byte(nid)
  1922  	partial := string(chars[0 : len(chars)/2])
  1923  	req, err = http.NewRequest("GET", "/v1.19/networks?partial-id="+partial, nil)
  1924  	if err != nil {
  1925  		t.Fatal(err)
  1926  	}
  1927  	handleRequest(rsp, req)
  1928  	if rsp.statusCode != http.StatusOK {
  1929  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  1930  	}
  1931  
  1932  	err = json.Unmarshal(rsp.body, &list)
  1933  	if err != nil {
  1934  		t.Fatal(err)
  1935  	}
  1936  	if len(list) == 0 {
  1937  		t.Fatalf("Expected non empty list")
  1938  	}
  1939  	if list[0].Name != "network-fiftyfive" || nid != list[0].ID {
  1940  		t.Fatalf("Incongruent resource found: %v", list[0])
  1941  	}
  1942  
  1943  	// Get network by id
  1944  	req, err = http.NewRequest("GET", "/v1.19/networks/"+nid, nil)
  1945  	if err != nil {
  1946  		t.Fatal(err)
  1947  	}
  1948  	handleRequest(rsp, req)
  1949  	if rsp.statusCode != http.StatusOK {
  1950  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  1951  	}
  1952  
  1953  	var nwr networkResource
  1954  	err = json.Unmarshal(rsp.body, &nwr)
  1955  	if err != nil {
  1956  		t.Fatal(err)
  1957  	}
  1958  	if nwr.Name != "network-fiftyfive" || nid != nwr.ID {
  1959  		t.Fatalf("Incongruent resource found: %v", nwr)
  1960  	}
  1961  
  1962  	// Create endpoint
  1963  	eb, err := json.Marshal(endpointCreate{Name: "ep-TwentyTwo"})
  1964  	if err != nil {
  1965  		t.Fatal(err)
  1966  	}
  1967  
  1968  	lr = newLocalReader(eb)
  1969  	req, err = http.NewRequest("POST", "/v1.19/networks/"+nid+"/endpoints", lr)
  1970  	if err != nil {
  1971  		t.Fatal(err)
  1972  	}
  1973  	handleRequest(rsp, req)
  1974  	if rsp.statusCode != http.StatusCreated {
  1975  		t.Fatalf("Unexpectded status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body))
  1976  	}
  1977  	if len(rsp.body) == 0 {
  1978  		t.Fatalf("Empty response body")
  1979  	}
  1980  
  1981  	var eid string
  1982  	err = json.Unmarshal(rsp.body, &eid)
  1983  	if err != nil {
  1984  		t.Fatal(err)
  1985  	}
  1986  
  1987  	// Query endpoint(s)
  1988  	req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints", nil)
  1989  	if err != nil {
  1990  		t.Fatal(err)
  1991  	}
  1992  	handleRequest(rsp, req)
  1993  	if rsp.statusCode != http.StatusOK {
  1994  		t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body)
  1995  	}
  1996  
  1997  	req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?name=bla", nil)
  1998  	if err != nil {
  1999  		t.Fatal(err)
  2000  	}
  2001  	handleRequest(rsp, req)
  2002  	if rsp.statusCode != http.StatusOK {
  2003  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2004  	}
  2005  	var epList []*endpointResource
  2006  	err = json.Unmarshal(rsp.body, &epList)
  2007  	if err != nil {
  2008  		t.Fatal(err)
  2009  	}
  2010  	if len(epList) != 0 {
  2011  		t.Fatalf("Expected empty list. Got %v", epList)
  2012  	}
  2013  
  2014  	// Query endpoint by name
  2015  	req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?name=ep-TwentyTwo", nil)
  2016  	if err != nil {
  2017  		t.Fatal(err)
  2018  	}
  2019  	handleRequest(rsp, req)
  2020  	if rsp.statusCode != http.StatusOK {
  2021  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2022  	}
  2023  
  2024  	err = json.Unmarshal(rsp.body, &epList)
  2025  	if err != nil {
  2026  		t.Fatal(err)
  2027  	}
  2028  	if len(epList) == 0 {
  2029  		t.Fatalf("Empty response body")
  2030  	}
  2031  	if epList[0].Name != "ep-TwentyTwo" || eid != epList[0].ID {
  2032  		t.Fatalf("Incongruent resource found: %v", epList[0])
  2033  	}
  2034  
  2035  	// Query endpoint by partial id
  2036  	chars = []byte(eid)
  2037  	partial = string(chars[0 : len(chars)/2])
  2038  	req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?partial-id="+partial, nil)
  2039  	if err != nil {
  2040  		t.Fatal(err)
  2041  	}
  2042  	handleRequest(rsp, req)
  2043  	if rsp.statusCode != http.StatusOK {
  2044  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2045  	}
  2046  
  2047  	err = json.Unmarshal(rsp.body, &epList)
  2048  	if err != nil {
  2049  		t.Fatal(err)
  2050  	}
  2051  	if len(epList) == 0 {
  2052  		t.Fatalf("Empty response body")
  2053  	}
  2054  	if epList[0].Name != "ep-TwentyTwo" || eid != epList[0].ID {
  2055  		t.Fatalf("Incongruent resource found: %v", epList[0])
  2056  	}
  2057  
  2058  	// Get endpoint by id
  2059  	req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints/"+eid, nil)
  2060  	if err != nil {
  2061  		t.Fatal(err)
  2062  	}
  2063  	handleRequest(rsp, req)
  2064  	if rsp.statusCode != http.StatusOK {
  2065  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2066  	}
  2067  
  2068  	var epr endpointResource
  2069  	err = json.Unmarshal(rsp.body, &epr)
  2070  	if err != nil {
  2071  		t.Fatal(err)
  2072  	}
  2073  	if epr.Name != "ep-TwentyTwo" || epr.ID != eid {
  2074  		t.Fatalf("Incongruent resource found: %v", epr)
  2075  	}
  2076  
  2077  	// Store two container ids and one partial ids
  2078  	cid1 := "container10010000000"
  2079  	cid2 := "container20010000000"
  2080  	chars = []byte(cid1)
  2081  	cpid1 := string(chars[0 : len(chars)/2])
  2082  
  2083  	// Create sandboxes
  2084  	sb1, err := json.Marshal(sandboxCreate{
  2085  		ContainerID: cid1,
  2086  		PortMapping: getPortMapping(),
  2087  	})
  2088  	if err != nil {
  2089  		t.Fatal(err)
  2090  	}
  2091  
  2092  	lr = newLocalReader(sb1)
  2093  	req, err = http.NewRequest("POST", "/v5.22/sandboxes", lr)
  2094  	if err != nil {
  2095  		t.Fatal(err)
  2096  	}
  2097  	handleRequest(rsp, req)
  2098  	if rsp.statusCode != http.StatusCreated {
  2099  		t.Fatalf("Unexpectded status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body))
  2100  	}
  2101  	if len(rsp.body) == 0 {
  2102  		t.Fatalf("Empty response body")
  2103  	}
  2104  	// Get sandbox id and partial id
  2105  	var sid1 string
  2106  	err = json.Unmarshal(rsp.body, &sid1)
  2107  	if err != nil {
  2108  		t.Fatal(err)
  2109  	}
  2110  
  2111  	sb2, err := json.Marshal(sandboxCreate{
  2112  		ContainerID:  cid2,
  2113  		ExposedPorts: getExposedPorts(),
  2114  	})
  2115  	if err != nil {
  2116  		t.Fatal(err)
  2117  	}
  2118  
  2119  	lr = newLocalReader(sb2)
  2120  	req, err = http.NewRequest("POST", "/v5.22/sandboxes", lr)
  2121  	if err != nil {
  2122  		t.Fatal(err)
  2123  	}
  2124  	handleRequest(rsp, req)
  2125  	if rsp.statusCode != http.StatusCreated {
  2126  		t.Fatalf("Unexpectded status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body))
  2127  	}
  2128  	if len(rsp.body) == 0 {
  2129  		t.Fatalf("Empty response body")
  2130  	}
  2131  	// Get sandbox id and partial id
  2132  	var sid2 string
  2133  	err = json.Unmarshal(rsp.body, &sid2)
  2134  	if err != nil {
  2135  		t.Fatal(err)
  2136  	}
  2137  	chars = []byte(sid2)
  2138  	spid2 := string(chars[0 : len(chars)/2])
  2139  
  2140  	// Query sandboxes
  2141  	req, err = http.NewRequest("GET", "/sandboxes", nil)
  2142  	if err != nil {
  2143  		t.Fatal(err)
  2144  	}
  2145  	handleRequest(rsp, req)
  2146  	if rsp.statusCode != http.StatusOK {
  2147  		t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body)
  2148  	}
  2149  
  2150  	var sbList []*sandboxResource
  2151  	err = json.Unmarshal(rsp.body, &sbList)
  2152  	if err != nil {
  2153  		t.Fatal(err)
  2154  	}
  2155  	if len(sbList) != 2 {
  2156  		t.Fatalf("Expected 2 elements in list. Got %v", sbList)
  2157  	}
  2158  
  2159  	// Get sandbox by id
  2160  	req, err = http.NewRequest("GET", "/sandboxes/"+sid1, nil)
  2161  	if err != nil {
  2162  		t.Fatal(err)
  2163  	}
  2164  	handleRequest(rsp, req)
  2165  	if rsp.statusCode != http.StatusOK {
  2166  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2167  	}
  2168  
  2169  	var sbr sandboxResource
  2170  	err = json.Unmarshal(rsp.body, &sbr)
  2171  	if err != nil {
  2172  		t.Fatal(err)
  2173  	}
  2174  	if sbr.ContainerID != cid1 {
  2175  		t.Fatalf("Incongruent resource found: %v", sbr)
  2176  	}
  2177  
  2178  	// Query sandbox by partial sandbox id
  2179  	req, err = http.NewRequest("GET", "/sandboxes?partial-id="+spid2, nil)
  2180  	if err != nil {
  2181  		t.Fatal(err)
  2182  	}
  2183  	handleRequest(rsp, req)
  2184  	if rsp.statusCode != http.StatusOK {
  2185  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2186  	}
  2187  
  2188  	err = json.Unmarshal(rsp.body, &sbList)
  2189  	if err != nil {
  2190  		t.Fatal(err)
  2191  	}
  2192  	if len(sbList) == 0 {
  2193  		t.Fatalf("Empty response body")
  2194  	}
  2195  	if sbList[0].ID != sid2 {
  2196  		t.Fatalf("Incongruent resource found: %v", sbList[0])
  2197  	}
  2198  
  2199  	// Query sandbox by container id
  2200  	req, err = http.NewRequest("GET", "/sandboxes?container-id="+cid2, nil)
  2201  	if err != nil {
  2202  		t.Fatal(err)
  2203  	}
  2204  	handleRequest(rsp, req)
  2205  	if rsp.statusCode != http.StatusOK {
  2206  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2207  	}
  2208  
  2209  	err = json.Unmarshal(rsp.body, &sbList)
  2210  	if err != nil {
  2211  		t.Fatal(err)
  2212  	}
  2213  	if len(sbList) == 0 {
  2214  		t.Fatalf("Empty response body")
  2215  	}
  2216  	if sbList[0].ContainerID != cid2 {
  2217  		t.Fatalf("Incongruent resource found: %v", sbList[0])
  2218  	}
  2219  
  2220  	// Query sandbox by partial container id
  2221  	req, err = http.NewRequest("GET", "/sandboxes?partial-container-id="+cpid1, nil)
  2222  	if err != nil {
  2223  		t.Fatal(err)
  2224  	}
  2225  	handleRequest(rsp, req)
  2226  	if rsp.statusCode != http.StatusOK {
  2227  		t.Fatalf("Unexpectded failure: (%d): %s", rsp.statusCode, rsp.body)
  2228  	}
  2229  
  2230  	err = json.Unmarshal(rsp.body, &sbList)
  2231  	if err != nil {
  2232  		t.Fatal(err)
  2233  	}
  2234  	if len(sbList) == 0 {
  2235  		t.Fatalf("Empty response body")
  2236  	}
  2237  	if sbList[0].ContainerID != cid1 {
  2238  		t.Fatalf("Incongruent resource found: %v", sbList[0])
  2239  	}
  2240  }
  2241  
  2242  func TestEndToEndErrorMessage(t *testing.T) {
  2243  	defer testutils.SetupTestOSContext(t)()
  2244  
  2245  	rsp := newWriter()
  2246  
  2247  	// Cleanup local datastore file
  2248  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
  2249  
  2250  	c, err := libnetwork.New()
  2251  	if err != nil {
  2252  		t.Fatal(err)
  2253  	}
  2254  	defer c.Stop()
  2255  	handleRequest := NewHTTPHandler(c)
  2256  
  2257  	body := []byte{}
  2258  	lr := newLocalReader(body)
  2259  	req, err := http.NewRequest("POST", "/v1.19/networks", lr)
  2260  	if err != nil {
  2261  		t.Fatal(err)
  2262  	}
  2263  	handleRequest(rsp, req)
  2264  
  2265  	if len(rsp.body) == 0 {
  2266  		t.Fatalf("Empty response body.")
  2267  	}
  2268  	empty := []byte("\"\"")
  2269  	if bytes.Equal(empty, bytes.TrimSpace(rsp.body)) {
  2270  		t.Fatalf("Empty response error message.")
  2271  	}
  2272  }
  2273  
  2274  type bre struct{}
  2275  
  2276  func (b *bre) Error() string {
  2277  	return "I am a bad request error"
  2278  }
  2279  func (b *bre) BadRequest() {}
  2280  
  2281  type nfe struct{}
  2282  
  2283  func (n *nfe) Error() string {
  2284  	return "I am a not found error"
  2285  }
  2286  func (n *nfe) NotFound() {}
  2287  
  2288  type forb struct{}
  2289  
  2290  func (f *forb) Error() string {
  2291  	return "I am a bad request error"
  2292  }
  2293  func (f *forb) Forbidden() {}
  2294  
  2295  type notimpl struct{}
  2296  
  2297  func (nip *notimpl) Error() string {
  2298  	return "I am a not implemented error"
  2299  }
  2300  func (nip *notimpl) NotImplemented() {}
  2301  
  2302  type inter struct{}
  2303  
  2304  func (it *inter) Error() string {
  2305  	return "I am an internal error"
  2306  }
  2307  func (it *inter) Internal() {}
  2308  
  2309  type tout struct{}
  2310  
  2311  func (to *tout) Error() string {
  2312  	return "I am a timeout error"
  2313  }
  2314  func (to *tout) Timeout() {}
  2315  
  2316  type noserv struct{}
  2317  
  2318  func (nos *noserv) Error() string {
  2319  	return "I am a no service error"
  2320  }
  2321  func (nos *noserv) NoService() {}
  2322  
  2323  type notclassified struct{}
  2324  
  2325  func (noc *notclassified) Error() string {
  2326  	return "I am a non classified error"
  2327  }
  2328  
  2329  func TestErrorConversion(t *testing.T) {
  2330  	if convertNetworkError(new(bre)).StatusCode != http.StatusBadRequest {
  2331  		t.Fatalf("Failed to recognize BadRequest error")
  2332  	}
  2333  
  2334  	if convertNetworkError(new(nfe)).StatusCode != http.StatusNotFound {
  2335  		t.Fatalf("Failed to recognize NotFound error")
  2336  	}
  2337  
  2338  	if convertNetworkError(new(forb)).StatusCode != http.StatusForbidden {
  2339  		t.Fatalf("Failed to recognize Forbidden error")
  2340  	}
  2341  
  2342  	if convertNetworkError(new(notimpl)).StatusCode != http.StatusNotImplemented {
  2343  		t.Fatalf("Failed to recognize NotImplemented error")
  2344  	}
  2345  
  2346  	if convertNetworkError(new(inter)).StatusCode != http.StatusInternalServerError {
  2347  		t.Fatalf("Failed to recognize Internal error")
  2348  	}
  2349  
  2350  	if convertNetworkError(new(tout)).StatusCode != http.StatusRequestTimeout {
  2351  		t.Fatalf("Failed to recognize Timeout error")
  2352  	}
  2353  
  2354  	if convertNetworkError(new(noserv)).StatusCode != http.StatusServiceUnavailable {
  2355  		t.Fatalf("Failed to recognize No Service error")
  2356  	}
  2357  
  2358  	if convertNetworkError(new(notclassified)).StatusCode != http.StatusInternalServerError {
  2359  		t.Fatalf("Failed to recognize not classified error as Internal error")
  2360  	}
  2361  }
  2362  
  2363  func TestFieldRegex(t *testing.T) {
  2364  	pr := regexp.MustCompile(regex)
  2365  	qr := regexp.MustCompile(`^` + qregx + `$`) // mux compiles it like this
  2366  
  2367  	if pr.MatchString("") {
  2368  		t.Fatalf("Unexpected match")
  2369  	}
  2370  	if !qr.MatchString("") {
  2371  		t.Fatalf("Unexpected match failure")
  2372  	}
  2373  
  2374  	if pr.MatchString(":") {
  2375  		t.Fatalf("Unexpected match")
  2376  	}
  2377  	if qr.MatchString(":") {
  2378  		t.Fatalf("Unexpected match")
  2379  	}
  2380  
  2381  	if pr.MatchString(".") {
  2382  		t.Fatalf("Unexpected match")
  2383  	}
  2384  	if qr.MatchString(".") {
  2385  		t.Fatalf("Unexpected match")
  2386  	}
  2387  }