github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/compute/v2/servers/testing/fixtures.go (about)

     1  package testing
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/huaweicloud/golangsdk"
    10  	"github.com/huaweicloud/golangsdk/openstack/compute/v2/servers"
    11  	th "github.com/huaweicloud/golangsdk/testhelper"
    12  	"github.com/huaweicloud/golangsdk/testhelper/client"
    13  )
    14  
    15  // ServerListBody contains the canned body of a servers.List response.
    16  const ServerListBody = `
    17  {
    18  	"servers": [
    19  		{
    20  			"status": "ACTIVE",
    21  			"updated": "2014-09-25T13:10:10Z",
    22  			"hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
    23  			"OS-EXT-SRV-ATTR:host": "devstack",
    24  			"addresses": {
    25  				"private": [
    26  					{
    27  						"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:7c:1b:2b",
    28  						"version": 4,
    29  						"addr": "10.0.0.32",
    30  						"OS-EXT-IPS:type": "fixed"
    31  					}
    32  				]
    33  			},
    34  			"links": [
    35  				{
    36  					"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5",
    37  					"rel": "self"
    38  				},
    39  				{
    40  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5",
    41  					"rel": "bookmark"
    42  				}
    43  			],
    44  			"key_name": null,
    45  			"image": {
    46  				"id": "f90f6034-2570-4974-8351-6b49732ef2eb",
    47  				"links": [
    48  					{
    49  						"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
    50  						"rel": "bookmark"
    51  					}
    52  				]
    53  			},
    54  			"OS-EXT-STS:task_state": null,
    55  			"OS-EXT-STS:vm_state": "active",
    56  			"OS-EXT-SRV-ATTR:instance_name": "instance-0000001e",
    57  			"OS-SRV-USG:launched_at": "2014-09-25T13:10:10.000000",
    58  			"OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack",
    59  			"flavor": {
    60  				"id": "1",
    61  				"links": [
    62  					{
    63  						"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
    64  						"rel": "bookmark"
    65  					}
    66  				]
    67  			},
    68  			"id": "ef079b0c-e610-4dfb-b1aa-b49f07ac48e5",
    69  			"security_groups": [
    70  				{
    71  					"name": "default"
    72  				}
    73  			],
    74  			"OS-SRV-USG:terminated_at": null,
    75  			"OS-EXT-AZ:availability_zone": "nova",
    76  			"user_id": "9349aff8be7545ac9d2f1d00999a23cd",
    77  			"name": "herp",
    78  			"created": "2014-09-25T13:10:02Z",
    79  			"tenant_id": "fcad67a6189847c4aecfa3c81a05783b",
    80  			"OS-DCF:diskConfig": "MANUAL",
    81  			"os-extended-volumes:volumes_attached": [
    82  				{
    83  					"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e"
    84  				}
    85  			],
    86  			"accessIPv4": "",
    87  			"accessIPv6": "",
    88  			"progress": 0,
    89  			"OS-EXT-STS:power_state": 1,
    90  			"config_drive": "",
    91  			"metadata": {}
    92  		},
    93  		{
    94  			"status": "ACTIVE",
    95  			"updated": "2014-09-25T13:04:49Z",
    96  			"hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
    97  			"OS-EXT-SRV-ATTR:host": "devstack",
    98  			"addresses": {
    99  				"private": [
   100  					{
   101  						"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be",
   102  						"version": 4,
   103  						"addr": "10.0.0.31",
   104  						"OS-EXT-IPS:type": "fixed"
   105  					}
   106  				]
   107  			},
   108  			"links": [
   109  				{
   110  					"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   111  					"rel": "self"
   112  				},
   113  				{
   114  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   115  					"rel": "bookmark"
   116  				}
   117  			],
   118  			"key_name": null,
   119  			"image": {
   120  				"id": "f90f6034-2570-4974-8351-6b49732ef2eb",
   121  				"links": [
   122  					{
   123  						"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
   124  						"rel": "bookmark"
   125  					}
   126  				]
   127  			},
   128  			"OS-EXT-STS:task_state": null,
   129  			"OS-EXT-STS:vm_state": "active",
   130  			"OS-EXT-SRV-ATTR:instance_name": "instance-0000001d",
   131  			"OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000",
   132  			"OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack",
   133  			"flavor": {
   134  				"id": "1",
   135  				"links": [
   136  					{
   137  						"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
   138  						"rel": "bookmark"
   139  					}
   140  				]
   141  			},
   142  			"id": "9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   143  			"security_groups": [
   144  				{
   145  					"name": "default"
   146  				}
   147  			],
   148  			"OS-SRV-USG:terminated_at": null,
   149  			"OS-EXT-AZ:availability_zone": "nova",
   150  			"user_id": "9349aff8be7545ac9d2f1d00999a23cd",
   151  			"name": "derp",
   152  			"created": "2014-09-25T13:04:41Z",
   153  			"tenant_id": "fcad67a6189847c4aecfa3c81a05783b",
   154  			"OS-DCF:diskConfig": "MANUAL",
   155  			"os-extended-volumes:volumes_attached": [
   156  				{
   157  					"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e"
   158  				}
   159  			],
   160  			"accessIPv4": "",
   161  			"accessIPv6": "",
   162  			"progress": 0,
   163  			"OS-EXT-STS:power_state": 1,
   164  			"config_drive": "",
   165  			"metadata": {}
   166  		},
   167  		{
   168  		"status": "ACTIVE",
   169  		"updated": "2014-09-25T13:04:49Z",
   170  		"hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
   171  		"OS-EXT-SRV-ATTR:host": "devstack",
   172  		"addresses": {
   173  			"private": [
   174  				{
   175  					"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be",
   176  					"version": 4,
   177  					"addr": "10.0.0.31",
   178  					"OS-EXT-IPS:type": "fixed"
   179  				}
   180  			]
   181  		},
   182  		"links": [
   183  			{
   184  				"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   185  				"rel": "self"
   186  			},
   187  			{
   188  				"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   189  				"rel": "bookmark"
   190  			}
   191  		],
   192  		"key_name": null,
   193  		"image": "",
   194  		"OS-EXT-STS:task_state": null,
   195  		"OS-EXT-STS:vm_state": "active",
   196  		"OS-EXT-SRV-ATTR:instance_name": "instance-0000001d",
   197  		"OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000",
   198  		"OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack",
   199  		"flavor": {
   200  			"id": "1",
   201  			"links": [
   202  				{
   203  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
   204  					"rel": "bookmark"
   205  				}
   206  			]
   207  		},
   208  		"id": "9e5476bd-a4ec-4653-93d6-72c93aa682bb",
   209  		"security_groups": [
   210  			{
   211  				"name": "default"
   212  			}
   213  		],
   214  		"OS-SRV-USG:terminated_at": null,
   215  		"OS-EXT-AZ:availability_zone": "nova",
   216  		"user_id": "9349aff8be7545ac9d2f1d00999a23cd",
   217  		"name": "merp",
   218  		"created": "2014-09-25T13:04:41Z",
   219  		"tenant_id": "fcad67a6189847c4aecfa3c81a05783b",
   220  		"OS-DCF:diskConfig": "MANUAL",
   221  		"os-extended-volumes:volumes_attached": [
   222  			{
   223  				"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e"
   224  			}
   225  		],
   226  		"accessIPv4": "",
   227  		"accessIPv6": "",
   228  		"progress": 0,
   229  		"OS-EXT-STS:power_state": 1,
   230  		"config_drive": "",
   231  		"metadata": {}
   232  	}
   233  	]
   234  }
   235  `
   236  
   237  // SingleServerBody is the canned body of a Get request on an existing server.
   238  const SingleServerBody = `
   239  {
   240  	"server": {
   241  		"status": "ACTIVE",
   242  		"updated": "2014-09-25T13:04:49Z",
   243  		"hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
   244  		"OS-EXT-SRV-ATTR:host": "devstack",
   245  		"addresses": {
   246  			"private": [
   247  				{
   248  					"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be",
   249  					"version": 4,
   250  					"addr": "10.0.0.31",
   251  					"OS-EXT-IPS:type": "fixed"
   252  				}
   253  			]
   254  		},
   255  		"links": [
   256  			{
   257  				"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   258  				"rel": "self"
   259  			},
   260  			{
   261  				"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   262  				"rel": "bookmark"
   263  			}
   264  		],
   265  		"key_name": null,
   266  		"image": {
   267  			"id": "f90f6034-2570-4974-8351-6b49732ef2eb",
   268  			"links": [
   269  				{
   270  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
   271  					"rel": "bookmark"
   272  				}
   273  			]
   274  		},
   275  		"OS-EXT-STS:task_state": null,
   276  		"OS-EXT-STS:vm_state": "active",
   277  		"OS-EXT-SRV-ATTR:instance_name": "instance-0000001d",
   278  		"OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000",
   279  		"OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack",
   280  		"flavor": {
   281  			"id": "1",
   282  			"links": [
   283  				{
   284  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
   285  					"rel": "bookmark"
   286  				}
   287  			]
   288  		},
   289  		"id": "9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   290  		"security_groups": [
   291  			{
   292  				"name": "default"
   293  			}
   294  		],
   295  		"OS-SRV-USG:terminated_at": null,
   296  		"OS-EXT-AZ:availability_zone": "nova",
   297  		"user_id": "9349aff8be7545ac9d2f1d00999a23cd",
   298  		"name": "derp",
   299  		"created": "2014-09-25T13:04:41Z",
   300  		"tenant_id": "fcad67a6189847c4aecfa3c81a05783b",
   301  		"OS-DCF:diskConfig": "MANUAL",
   302  		"os-extended-volumes:volumes_attached": [
   303  			{
   304  				"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e"
   305  			}
   306  		],
   307  		"accessIPv4": "",
   308  		"accessIPv6": "",
   309  		"progress": 0,
   310  		"OS-EXT-STS:power_state": 1,
   311  		"config_drive": "",
   312  		"metadata": {}
   313  	}
   314  }
   315  `
   316  
   317  // FaultyServerBody is the body of a Get request on an existing server
   318  // which has a fault/error.
   319  const FaultyServerBody = `
   320  {
   321  	"server": {
   322  		"status": "ACTIVE",
   323  		"updated": "2014-09-25T13:04:49Z",
   324  		"hostId": "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
   325  		"OS-EXT-SRV-ATTR:host": "devstack",
   326  		"addresses": {
   327  			"private": [
   328  				{
   329  					"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be",
   330  					"version": 4,
   331  					"addr": "10.0.0.31",
   332  					"OS-EXT-IPS:type": "fixed"
   333  				}
   334  			]
   335  		},
   336  		"links": [
   337  			{
   338  				"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   339  				"rel": "self"
   340  			},
   341  			{
   342  				"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   343  				"rel": "bookmark"
   344  			}
   345  		],
   346  		"key_name": null,
   347  		"image": {
   348  			"id": "f90f6034-2570-4974-8351-6b49732ef2eb",
   349  			"links": [
   350  				{
   351  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
   352  					"rel": "bookmark"
   353  				}
   354  			]
   355  		},
   356  		"OS-EXT-STS:task_state": null,
   357  		"OS-EXT-STS:vm_state": "active",
   358  		"OS-EXT-SRV-ATTR:instance_name": "instance-0000001d",
   359  		"OS-SRV-USG:launched_at": "2014-09-25T13:04:49.000000",
   360  		"OS-EXT-SRV-ATTR:hypervisor_hostname": "devstack",
   361  		"flavor": {
   362  			"id": "1",
   363  			"links": [
   364  				{
   365  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
   366  					"rel": "bookmark"
   367  				}
   368  			]
   369  		},
   370  		"id": "9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   371  		"security_groups": [
   372  			{
   373  				"name": "default"
   374  			}
   375  		],
   376  		"OS-SRV-USG:terminated_at": null,
   377  		"OS-EXT-AZ:availability_zone": "nova",
   378  		"user_id": "9349aff8be7545ac9d2f1d00999a23cd",
   379  		"name": "derp",
   380  		"created": "2014-09-25T13:04:41Z",
   381  		"tenant_id": "fcad67a6189847c4aecfa3c81a05783b",
   382  		"OS-DCF:diskConfig": "MANUAL",
   383  		"os-extended-volumes:volumes_attached": [
   384  			{
   385  				"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e"
   386  			}
   387  		],
   388  		"accessIPv4": "",
   389  		"accessIPv6": "",
   390  		"progress": 0,
   391  		"OS-EXT-STS:power_state": 1,
   392  		"config_drive": "",
   393  		"metadata": {},
   394  		"fault": {
   395  			"message": "Conflict updating instance c2ce4dea-b73f-4d01-8633-2c6032869281. Expected: {'task_state': [u'spawning']}. Actual: {'task_state': None}",
   396  			"code": 500,
   397  			"created": "2017-11-11T07:58:39Z",
   398  			"details": "Stock details for test"
   399  		}
   400  	}
   401  }
   402  `
   403  
   404  const ServerPasswordBody = `
   405  {
   406      "password": "xlozO3wLCBRWAa2yDjCCVx8vwNPypxnypmRYDa/zErlQ+EzPe1S/Gz6nfmC52mOlOSCRuUOmG7kqqgejPof6M7bOezS387zjq4LSvvwp28zUknzy4YzfFGhnHAdai3TxUJ26pfQCYrq8UTzmKF2Bq8ioSEtVVzM0A96pDh8W2i7BOz6MdoiVyiev/I1K2LsuipfxSJR7Wdke4zNXJjHHP2RfYsVbZ/k9ANu+Nz4iIH8/7Cacud/pphH7EjrY6a4RZNrjQskrhKYed0YERpotyjYk1eDtRe72GrSiXteqCM4biaQ5w3ruS+AcX//PXk3uJ5kC7d67fPXaVz4WaQRYMg=="
   407  }
   408  `
   409  
   410  const ConsoleOutputBody = `{
   411  	"output": "abc"
   412  }`
   413  
   414  var (
   415  	herpTimeCreated, _ = time.Parse(time.RFC3339, "2014-09-25T13:10:02Z")
   416  	herpTimeUpdated, _ = time.Parse(time.RFC3339, "2014-09-25T13:10:10Z")
   417  	// ServerHerp is a Server struct that should correspond to the first result in ServerListBody.
   418  	ServerHerp = servers.Server{
   419  		Status:  "ACTIVE",
   420  		Updated: herpTimeUpdated,
   421  		HostID:  "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
   422  		Addresses: map[string]interface{}{
   423  			"private": []interface{}{
   424  				map[string]interface{}{
   425  					"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:7c:1b:2b",
   426  					"version":                 float64(4),
   427  					"addr":                    "10.0.0.32",
   428  					"OS-EXT-IPS:type":         "fixed",
   429  				},
   430  			},
   431  		},
   432  		Links: []interface{}{
   433  			map[string]interface{}{
   434  				"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5",
   435  				"rel":  "self",
   436  			},
   437  			map[string]interface{}{
   438  				"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/ef079b0c-e610-4dfb-b1aa-b49f07ac48e5",
   439  				"rel":  "bookmark",
   440  			},
   441  		},
   442  		Image: map[string]interface{}{
   443  			"id": "f90f6034-2570-4974-8351-6b49732ef2eb",
   444  			"links": []interface{}{
   445  				map[string]interface{}{
   446  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
   447  					"rel":  "bookmark",
   448  				},
   449  			},
   450  		},
   451  		Flavor: map[string]interface{}{
   452  			"id": "1",
   453  			"links": []interface{}{
   454  				map[string]interface{}{
   455  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
   456  					"rel":  "bookmark",
   457  				},
   458  			},
   459  		},
   460  		ID:       "ef079b0c-e610-4dfb-b1aa-b49f07ac48e5",
   461  		UserID:   "9349aff8be7545ac9d2f1d00999a23cd",
   462  		Name:     "herp",
   463  		Created:  herpTimeCreated,
   464  		TenantID: "fcad67a6189847c4aecfa3c81a05783b",
   465  		Metadata: map[string]string{},
   466  		SecurityGroups: []map[string]interface{}{
   467  			{
   468  				"name": "default",
   469  			},
   470  		},
   471  		VolumesAttached: []map[string]string{
   472  			{
   473  				"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e",
   474  			},
   475  		},
   476  	}
   477  
   478  	derpTimeCreated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:41Z")
   479  	derpTimeUpdated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:49Z")
   480  	// ServerDerp is a Server struct that should correspond to the second server in ServerListBody.
   481  	ServerDerp = servers.Server{
   482  		Status:  "ACTIVE",
   483  		Updated: derpTimeUpdated,
   484  		HostID:  "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
   485  		Addresses: map[string]interface{}{
   486  			"private": []interface{}{
   487  				map[string]interface{}{
   488  					"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be",
   489  					"version":                 float64(4),
   490  					"addr":                    "10.0.0.31",
   491  					"OS-EXT-IPS:type":         "fixed",
   492  				},
   493  			},
   494  		},
   495  		Links: []interface{}{
   496  			map[string]interface{}{
   497  				"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   498  				"rel":  "self",
   499  			},
   500  			map[string]interface{}{
   501  				"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   502  				"rel":  "bookmark",
   503  			},
   504  		},
   505  		Image: map[string]interface{}{
   506  			"id": "f90f6034-2570-4974-8351-6b49732ef2eb",
   507  			"links": []interface{}{
   508  				map[string]interface{}{
   509  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
   510  					"rel":  "bookmark",
   511  				},
   512  			},
   513  		},
   514  		Flavor: map[string]interface{}{
   515  			"id": "1",
   516  			"links": []interface{}{
   517  				map[string]interface{}{
   518  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
   519  					"rel":  "bookmark",
   520  				},
   521  			},
   522  		},
   523  		ID:       "9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   524  		UserID:   "9349aff8be7545ac9d2f1d00999a23cd",
   525  		Name:     "derp",
   526  		Created:  derpTimeCreated,
   527  		TenantID: "fcad67a6189847c4aecfa3c81a05783b",
   528  		Metadata: map[string]string{},
   529  		SecurityGroups: []map[string]interface{}{
   530  			{
   531  				"name": "default",
   532  			},
   533  		},
   534  		VolumesAttached: []map[string]string{
   535  			{
   536  				"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e",
   537  			},
   538  		},
   539  	}
   540  
   541  	ConsoleOutput = "abc"
   542  
   543  	merpTimeCreated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:41Z")
   544  	merpTimeUpdated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:49Z")
   545  	// ServerMerp is a Server struct that should correspond to the second server in ServerListBody.
   546  	ServerMerp = servers.Server{
   547  		Status:  "ACTIVE",
   548  		Updated: merpTimeUpdated,
   549  		HostID:  "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
   550  		Addresses: map[string]interface{}{
   551  			"private": []interface{}{
   552  				map[string]interface{}{
   553  					"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9e:89:be",
   554  					"version":                 float64(4),
   555  					"addr":                    "10.0.0.31",
   556  					"OS-EXT-IPS:type":         "fixed",
   557  				},
   558  			},
   559  		},
   560  		Links: []interface{}{
   561  			map[string]interface{}{
   562  				"href": "http://104.130.131.164:8774/v2/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   563  				"rel":  "self",
   564  			},
   565  			map[string]interface{}{
   566  				"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/servers/9e5476bd-a4ec-4653-93d6-72c93aa682ba",
   567  				"rel":  "bookmark",
   568  			},
   569  		},
   570  		Image: nil,
   571  		Flavor: map[string]interface{}{
   572  			"id": "1",
   573  			"links": []interface{}{
   574  				map[string]interface{}{
   575  					"href": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/flavors/1",
   576  					"rel":  "bookmark",
   577  				},
   578  			},
   579  		},
   580  		ID:       "9e5476bd-a4ec-4653-93d6-72c93aa682bb",
   581  		UserID:   "9349aff8be7545ac9d2f1d00999a23cd",
   582  		Name:     "merp",
   583  		Created:  merpTimeCreated,
   584  		TenantID: "fcad67a6189847c4aecfa3c81a05783b",
   585  		Metadata: map[string]string{},
   586  		SecurityGroups: []map[string]interface{}{
   587  			{
   588  				"name": "default",
   589  			},
   590  		},
   591  		VolumesAttached: []map[string]string{
   592  			{
   593  				"id": "cfb68a5e-203f-446d-9fd7-74b7e1f9722e",
   594  			},
   595  		},
   596  	}
   597  
   598  	faultTimeCreated, _ = time.Parse(time.RFC3339, "2017-11-11T07:58:39Z")
   599  	DerpFault           = servers.Fault{
   600  		Code:    500,
   601  		Created: faultTimeCreated,
   602  		Details: "Stock details for test",
   603  		Message: "Conflict updating instance c2ce4dea-b73f-4d01-8633-2c6032869281. " +
   604  			"Expected: {'task_state': [u'spawning']}. Actual: {'task_state': None}",
   605  	}
   606  )
   607  
   608  type CreateOptsWithCustomField struct {
   609  	servers.CreateOpts
   610  	Foo string `json:"foo,omitempty"`
   611  }
   612  
   613  func (opts CreateOptsWithCustomField) ToServerCreateMap() (map[string]interface{}, error) {
   614  	return golangsdk.BuildRequestBody(opts, "server")
   615  }
   616  
   617  // HandleServerCreationSuccessfully sets up the test server to respond to a server creation request
   618  // with a given response.
   619  func HandleServerCreationSuccessfully(t *testing.T, response string) {
   620  	th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) {
   621  		th.TestMethod(t, r, "POST")
   622  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   623  		th.TestJSONRequest(t, r, `{
   624  			"server": {
   625  				"name": "derp",
   626  				"imageRef": "f90f6034-2570-4974-8351-6b49732ef2eb",
   627  				"flavorRef": "1"
   628  			}
   629  		}`)
   630  
   631  		w.WriteHeader(http.StatusAccepted)
   632  		w.Header().Add("Content-Type", "application/json")
   633  		fmt.Fprintf(w, response)
   634  	})
   635  
   636  	th.Mux.HandleFunc("/images/detail", func(w http.ResponseWriter, r *http.Request) {
   637  		th.TestMethod(t, r, "GET")
   638  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   639  
   640  		w.Header().Add("Content-Type", "application/json")
   641  		r.ParseForm()
   642  		marker := r.Form.Get("marker")
   643  		switch marker {
   644  		case "":
   645  			fmt.Fprintf(w, `
   646  				{
   647  					"images": [
   648  						{
   649  							"status": "ACTIVE",
   650  							"updated": "2014-09-23T12:54:56Z",
   651  							"id": "f3e4a95d-1f4f-4989-97ce-f3a1fb8c04d7",
   652  							"OS-EXT-IMG-SIZE:size": 476704768,
   653  							"name": "F17-x86_64-cfntools",
   654  							"created": "2014-09-23T12:54:52Z",
   655  							"minDisk": 0,
   656  							"progress": 100,
   657  							"minRam": 0
   658  						},
   659  						{
   660  							"status": "ACTIVE",
   661  							"updated": "2014-09-23T12:51:43Z",
   662  							"id": "f90f6034-2570-4974-8351-6b49732ef2eb",
   663  							"OS-EXT-IMG-SIZE:size": 13167616,
   664  							"name": "cirros-0.3.2-x86_64-disk",
   665  							"created": "2014-09-23T12:51:42Z",
   666  							"minDisk": 0,
   667  							"progress": 100,
   668  							"minRam": 0
   669  						}
   670  					]
   671  				}
   672  			`)
   673  		case "2":
   674  			fmt.Fprintf(w, `{ "images": [] }`)
   675  		default:
   676  			t.Fatalf("Unexpected marker: [%s]", marker)
   677  		}
   678  	})
   679  
   680  	th.Mux.HandleFunc("/flavors/detail", func(w http.ResponseWriter, r *http.Request) {
   681  		th.TestMethod(t, r, "GET")
   682  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   683  
   684  		w.Header().Add("Content-Type", "application/json")
   685  		r.ParseForm()
   686  		marker := r.Form.Get("marker")
   687  		switch marker {
   688  		case "":
   689  			fmt.Fprintf(w, `
   690  						{
   691  							"flavors": [
   692  								{
   693  									"id": "1",
   694  									"name": "m1.tiny",
   695  									"disk": 1,
   696  									"ram": 512,
   697  									"vcpus": 1,
   698  									"swap":""
   699  								},
   700  								{
   701  									"id": "2",
   702  									"name": "m2.small",
   703  									"disk": 10,
   704  									"ram": 1024,
   705  									"vcpus": 2,
   706  									"swap": 1000
   707  								}
   708  							],
   709  							"flavors_links": [
   710  								{
   711  									"href": "%s/flavors/detail?marker=2",
   712  									"rel": "next"
   713  								}
   714  							]
   715  						}
   716  					`, th.Server.URL)
   717  		case "2":
   718  			fmt.Fprintf(w, `{ "flavors": [] }`)
   719  		default:
   720  			t.Fatalf("Unexpected marker: [%s]", marker)
   721  		}
   722  	})
   723  }
   724  
   725  // HandleServerCreationWithCustomFieldSuccessfully sets up the test server to respond to a server creation request
   726  // with a given response.
   727  func HandleServerCreationWithCustomFieldSuccessfully(t *testing.T, response string) {
   728  	th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) {
   729  		th.TestMethod(t, r, "POST")
   730  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   731  		th.TestJSONRequest(t, r, `{
   732  			"server": {
   733  				"name": "derp",
   734  				"imageRef": "f90f6034-2570-4974-8351-6b49732ef2eb",
   735  				"flavorRef": "1",
   736  				"foo": "bar"
   737  			}
   738  		}`)
   739  
   740  		w.WriteHeader(http.StatusAccepted)
   741  		w.Header().Add("Content-Type", "application/json")
   742  		fmt.Fprintf(w, response)
   743  	})
   744  }
   745  
   746  // HandleServerCreationWithUserdata sets up the test server to respond to a server creation request
   747  // with a given response.
   748  func HandleServerCreationWithUserdata(t *testing.T, response string) {
   749  	th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) {
   750  		th.TestMethod(t, r, "POST")
   751  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   752  		th.TestJSONRequest(t, r, `{
   753  			"server": {
   754  				"name": "derp",
   755  				"imageRef": "f90f6034-2570-4974-8351-6b49732ef2eb",
   756  				"flavorRef": "1",
   757  				"user_data": "dXNlcmRhdGEgc3RyaW5n"
   758  			}
   759  		}`)
   760  
   761  		w.WriteHeader(http.StatusAccepted)
   762  		w.Header().Add("Content-Type", "application/json")
   763  		fmt.Fprintf(w, response)
   764  	})
   765  }
   766  
   767  // HandleServerCreationWithMetadata sets up the test server to respond to a server creation request
   768  // with a given response.
   769  func HandleServerCreationWithMetadata(t *testing.T, response string) {
   770  	th.Mux.HandleFunc("/servers", func(w http.ResponseWriter, r *http.Request) {
   771  		th.TestMethod(t, r, "POST")
   772  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   773  		th.TestJSONRequest(t, r, `{
   774  			"server": {
   775  				"name": "derp",
   776  				"imageRef": "f90f6034-2570-4974-8351-6b49732ef2eb",
   777  				"flavorRef": "1",
   778  				"metadata": {
   779  					"abc": "def"
   780  				}
   781  			}
   782  		}`)
   783  
   784  		w.WriteHeader(http.StatusAccepted)
   785  		w.Header().Add("Content-Type", "application/json")
   786  		fmt.Fprintf(w, response)
   787  	})
   788  }
   789  
   790  // HandleServerListSuccessfully sets up the test server to respond to a server List request.
   791  func HandleServerListSuccessfully(t *testing.T) {
   792  	th.Mux.HandleFunc("/servers/detail", func(w http.ResponseWriter, r *http.Request) {
   793  		th.TestMethod(t, r, "GET")
   794  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   795  
   796  		w.Header().Add("Content-Type", "application/json")
   797  		r.ParseForm()
   798  		marker := r.Form.Get("marker")
   799  		switch marker {
   800  		case "":
   801  			fmt.Fprintf(w, ServerListBody)
   802  		case "9e5476bd-a4ec-4653-93d6-72c93aa682ba":
   803  			fmt.Fprintf(w, `{ "servers": [] }`)
   804  		default:
   805  			t.Fatalf("/servers/detail invoked with unexpected marker=[%s]", marker)
   806  		}
   807  	})
   808  }
   809  
   810  // HandleServerDeletionSuccessfully sets up the test server to respond to a server deletion request.
   811  func HandleServerDeletionSuccessfully(t *testing.T) {
   812  	th.Mux.HandleFunc("/servers/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) {
   813  		th.TestMethod(t, r, "DELETE")
   814  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   815  
   816  		w.WriteHeader(http.StatusNoContent)
   817  	})
   818  }
   819  
   820  // HandleServerForceDeletionSuccessfully sets up the test server to respond to a server force deletion
   821  // request.
   822  func HandleServerForceDeletionSuccessfully(t *testing.T) {
   823  	th.Mux.HandleFunc("/servers/asdfasdfasdf/action", func(w http.ResponseWriter, r *http.Request) {
   824  		th.TestMethod(t, r, "POST")
   825  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   826  		th.TestJSONRequest(t, r, `{ "forceDelete": "" }`)
   827  
   828  		w.WriteHeader(http.StatusAccepted)
   829  	})
   830  }
   831  
   832  // HandleServerGetSuccessfully sets up the test server to respond to a server Get request.
   833  func HandleServerGetSuccessfully(t *testing.T) {
   834  	th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) {
   835  		th.TestMethod(t, r, "GET")
   836  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   837  		th.TestHeader(t, r, "Accept", "application/json")
   838  
   839  		fmt.Fprintf(w, SingleServerBody)
   840  	})
   841  }
   842  
   843  // HandleServerGetFaultSuccessfully sets up the test server to respond to a server Get
   844  // request which contains a fault.
   845  func HandleServerGetFaultSuccessfully(t *testing.T) {
   846  	th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) {
   847  		th.TestMethod(t, r, "GET")
   848  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   849  		th.TestHeader(t, r, "Accept", "application/json")
   850  
   851  		fmt.Fprintf(w, FaultyServerBody)
   852  	})
   853  }
   854  
   855  // HandleServerUpdateSuccessfully sets up the test server to respond to a server Update request.
   856  func HandleServerUpdateSuccessfully(t *testing.T) {
   857  	th.Mux.HandleFunc("/servers/1234asdf", func(w http.ResponseWriter, r *http.Request) {
   858  		th.TestMethod(t, r, "PUT")
   859  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   860  		th.TestHeader(t, r, "Accept", "application/json")
   861  		th.TestHeader(t, r, "Content-Type", "application/json")
   862  		th.TestJSONRequest(t, r, `{ "server": { "name": "new-name" } }`)
   863  
   864  		fmt.Fprintf(w, SingleServerBody)
   865  	})
   866  }
   867  
   868  // HandleAdminPasswordChangeSuccessfully sets up the test server to respond to a server password
   869  // change request.
   870  func HandleAdminPasswordChangeSuccessfully(t *testing.T) {
   871  	th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) {
   872  		th.TestMethod(t, r, "POST")
   873  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   874  		th.TestJSONRequest(t, r, `{ "changePassword": { "adminPass": "new-password" } }`)
   875  
   876  		w.WriteHeader(http.StatusAccepted)
   877  	})
   878  }
   879  
   880  // HandleRebootSuccessfully sets up the test server to respond to a reboot request with success.
   881  func HandleRebootSuccessfully(t *testing.T) {
   882  	th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) {
   883  		th.TestMethod(t, r, "POST")
   884  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   885  		th.TestJSONRequest(t, r, `{ "reboot": { "type": "SOFT" } }`)
   886  
   887  		w.WriteHeader(http.StatusAccepted)
   888  	})
   889  }
   890  
   891  // HandleShowConsoleOutputSuccessfully sets up the test server to respond to a os-getConsoleOutput request with success.
   892  func HandleShowConsoleOutputSuccessfully(t *testing.T, response string) {
   893  	th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) {
   894  		th.TestMethod(t, r, "POST")
   895  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   896  		th.TestJSONRequest(t, r, `{ "os-getConsoleOutput": { "length": 50 } }`)
   897  
   898  		w.WriteHeader(http.StatusOK)
   899  		w.Header().Add("Content-Type", "application/json")
   900  		fmt.Fprintf(w, response)
   901  	})
   902  }
   903  
   904  // HandleRebuildSuccessfully sets up the test server to respond to a rebuild request with success.
   905  func HandleRebuildSuccessfully(t *testing.T, response string) {
   906  	th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) {
   907  		th.TestMethod(t, r, "POST")
   908  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   909  		th.TestJSONRequest(t, r, `
   910  			{
   911  				"rebuild": {
   912  					"name": "new-name",
   913  					"adminPass": "swordfish",
   914  					"imageRef": "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
   915  					"accessIPv4": "1.2.3.4"
   916  				}
   917  			}
   918  		`)
   919  
   920  		w.WriteHeader(http.StatusAccepted)
   921  		w.Header().Add("Content-Type", "application/json")
   922  		fmt.Fprintf(w, response)
   923  	})
   924  }
   925  
   926  // HandleMetadatumGetSuccessfully sets up the test server to respond to a metadatum Get request.
   927  func HandleMetadatumGetSuccessfully(t *testing.T) {
   928  	th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) {
   929  		th.TestMethod(t, r, "GET")
   930  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   931  		th.TestHeader(t, r, "Accept", "application/json")
   932  
   933  		w.WriteHeader(http.StatusOK)
   934  		w.Header().Add("Content-Type", "application/json")
   935  		w.Write([]byte(`{ "meta": {"foo":"bar"}}`))
   936  	})
   937  }
   938  
   939  // HandleMetadatumCreateSuccessfully sets up the test server to respond to a metadatum Create request.
   940  func HandleMetadatumCreateSuccessfully(t *testing.T) {
   941  	th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) {
   942  		th.TestMethod(t, r, "PUT")
   943  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   944  		th.TestJSONRequest(t, r, `{
   945  			"meta": {
   946  				"foo": "bar"
   947  			}
   948  		}`)
   949  
   950  		w.WriteHeader(http.StatusOK)
   951  		w.Header().Add("Content-Type", "application/json")
   952  		w.Write([]byte(`{ "meta": {"foo":"bar"}}`))
   953  	})
   954  }
   955  
   956  // HandleMetadatumDeleteSuccessfully sets up the test server to respond to a metadatum Delete request.
   957  func HandleMetadatumDeleteSuccessfully(t *testing.T) {
   958  	th.Mux.HandleFunc("/servers/1234asdf/metadata/foo", func(w http.ResponseWriter, r *http.Request) {
   959  		th.TestMethod(t, r, "DELETE")
   960  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   961  
   962  		w.WriteHeader(http.StatusNoContent)
   963  	})
   964  }
   965  
   966  // HandleMetadataGetSuccessfully sets up the test server to respond to a metadata Get request.
   967  func HandleMetadataGetSuccessfully(t *testing.T) {
   968  	th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) {
   969  		th.TestMethod(t, r, "GET")
   970  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   971  		th.TestHeader(t, r, "Accept", "application/json")
   972  
   973  		w.WriteHeader(http.StatusOK)
   974  		w.Write([]byte(`{ "metadata": {"foo":"bar", "this":"that"}}`))
   975  	})
   976  }
   977  
   978  // HandleMetadataResetSuccessfully sets up the test server to respond to a metadata Create request.
   979  func HandleMetadataResetSuccessfully(t *testing.T) {
   980  	th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) {
   981  		th.TestMethod(t, r, "PUT")
   982  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
   983  		th.TestJSONRequest(t, r, `{
   984  				"metadata": {
   985  					"foo": "bar",
   986  					"this": "that"
   987  				}
   988  			}`)
   989  
   990  		w.WriteHeader(http.StatusOK)
   991  		w.Header().Add("Content-Type", "application/json")
   992  		w.Write([]byte(`{ "metadata": {"foo":"bar", "this":"that"}}`))
   993  	})
   994  }
   995  
   996  // HandleMetadataUpdateSuccessfully sets up the test server to respond to a metadata Update request.
   997  func HandleMetadataUpdateSuccessfully(t *testing.T) {
   998  	th.Mux.HandleFunc("/servers/1234asdf/metadata", func(w http.ResponseWriter, r *http.Request) {
   999  		th.TestMethod(t, r, "POST")
  1000  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
  1001  		th.TestJSONRequest(t, r, `{
  1002  				"metadata": {
  1003  					"foo": "baz",
  1004  					"this": "those"
  1005  				}
  1006  			}`)
  1007  
  1008  		w.WriteHeader(http.StatusOK)
  1009  		w.Header().Add("Content-Type", "application/json")
  1010  		w.Write([]byte(`{ "metadata": {"foo":"baz", "this":"those"}}`))
  1011  	})
  1012  }
  1013  
  1014  // ListAddressesExpected represents an expected repsonse from a ListAddresses request.
  1015  var ListAddressesExpected = map[string][]servers.Address{
  1016  	"public": {
  1017  		{
  1018  			Version: 4,
  1019  			Address: "50.56.176.35",
  1020  		},
  1021  		{
  1022  			Version: 6,
  1023  			Address: "2001:4800:790e:510:be76:4eff:fe04:84a8",
  1024  		},
  1025  	},
  1026  	"private": {
  1027  		{
  1028  			Version: 4,
  1029  			Address: "10.180.3.155",
  1030  		},
  1031  	},
  1032  }
  1033  
  1034  // HandleAddressListSuccessfully sets up the test server to respond to a ListAddresses request.
  1035  func HandleAddressListSuccessfully(t *testing.T) {
  1036  	th.Mux.HandleFunc("/servers/asdfasdfasdf/ips", func(w http.ResponseWriter, r *http.Request) {
  1037  		th.TestMethod(t, r, "GET")
  1038  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
  1039  
  1040  		w.Header().Add("Content-Type", "application/json")
  1041  		fmt.Fprintf(w, `{
  1042  			"addresses": {
  1043  				"public": [
  1044  				{
  1045  					"version": 4,
  1046  					"addr": "50.56.176.35"
  1047  				},
  1048  				{
  1049  					"version": 6,
  1050  					"addr": "2001:4800:790e:510:be76:4eff:fe04:84a8"
  1051  				}
  1052  				],
  1053  				"private": [
  1054  				{
  1055  					"version": 4,
  1056  					"addr": "10.180.3.155"
  1057  				}
  1058  				]
  1059  			}
  1060  		}`)
  1061  	})
  1062  }
  1063  
  1064  // ListNetworkAddressesExpected represents an expected repsonse from a ListAddressesByNetwork request.
  1065  var ListNetworkAddressesExpected = []servers.Address{
  1066  	{
  1067  		Version: 4,
  1068  		Address: "50.56.176.35",
  1069  	},
  1070  	{
  1071  		Version: 6,
  1072  		Address: "2001:4800:790e:510:be76:4eff:fe04:84a8",
  1073  	},
  1074  }
  1075  
  1076  // HandleNetworkAddressListSuccessfully sets up the test server to respond to a ListAddressesByNetwork request.
  1077  func HandleNetworkAddressListSuccessfully(t *testing.T) {
  1078  	th.Mux.HandleFunc("/servers/asdfasdfasdf/ips/public", func(w http.ResponseWriter, r *http.Request) {
  1079  		th.TestMethod(t, r, "GET")
  1080  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
  1081  
  1082  		w.Header().Add("Content-Type", "application/json")
  1083  		fmt.Fprintf(w, `{
  1084  			"public": [
  1085  			{
  1086  				"version": 4,
  1087  				"addr": "50.56.176.35"
  1088  				},
  1089  				{
  1090  					"version": 6,
  1091  					"addr": "2001:4800:790e:510:be76:4eff:fe04:84a8"
  1092  				}
  1093  			]
  1094  			}`)
  1095  	})
  1096  }
  1097  
  1098  // HandleCreateServerImageSuccessfully sets up the test server to respond to a TestCreateServerImage request.
  1099  func HandleCreateServerImageSuccessfully(t *testing.T) {
  1100  	th.Mux.HandleFunc("/servers/serverimage/action", func(w http.ResponseWriter, r *http.Request) {
  1101  		th.TestMethod(t, r, "POST")
  1102  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
  1103  		w.Header().Add("Location", "https://0.0.0.0/images/xxxx-xxxxx-xxxxx-xxxx")
  1104  		w.WriteHeader(http.StatusAccepted)
  1105  	})
  1106  }
  1107  
  1108  // HandlePasswordGetSuccessfully sets up the test server to respond to a password Get request.
  1109  func HandlePasswordGetSuccessfully(t *testing.T) {
  1110  	th.Mux.HandleFunc("/servers/1234asdf/os-server-password", func(w http.ResponseWriter, r *http.Request) {
  1111  		th.TestMethod(t, r, "GET")
  1112  		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
  1113  		th.TestHeader(t, r, "Accept", "application/json")
  1114  
  1115  		fmt.Fprintf(w, ServerPasswordBody)
  1116  	})
  1117  }