It("Sends a request to set metadata to the RackHD API", func() {

			id := "55e79ea54e66816f6152fff9"
			cid := "vm-5678"
			metadata := map[string]interface{}{
				"stuff":  "definitely",
				"thing1": 3563456,
				"thing2": "bloop",
			}

			var metadataInput bosh.MethodArguments
			metadataInput = append(metadataInput, cid)
			metadataInput = append(metadataInput, metadata)

			expectedNodes := helpers.LoadNodes("../spec_assets/dummy_all_nodes_are_vms.json")
			expectedNodesData, err := json.Marshal(expectedNodes)
			Expect(err).ToNot(HaveOccurred())

			server.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("GET", "/api/common/nodes"),
					ghttp.RespondWith(http.StatusOK, expectedNodesData),
				),
				ghttp.VerifyRequest("PATCH", fmt.Sprintf("/api/common/nodes/%s", id)),
			)

			err = cpi.SetVMMetadata(cpiConfig, metadataInput)
			Expect(err).ToNot(HaveOccurred())

			Expect(server.ReceivedRequests()).To(HaveLen(2))
			jsonReader = strings.NewReader(fmt.Sprintf(`{"apiserver":"%s", "agent":{"blobstore": {"provider":"local","some": "options"}, "mbus":"localhost"}, "max_create_vm_attempts":1}`, serverURL.Host))
			request = bosh.CpiRequest{Method: bosh.HAS_VM}
			cpiConfig, err = config.New(jsonReader, request)
			Expect(err).ToNot(HaveOccurred())
		})

		AfterEach(func() {
			server.Close()
		})

		It("Find a vm that exist", func() {
			cid := "vm-1234"

			var metadataInput bosh.MethodArguments
			metadataInput = append(metadataInput, cid)
			expectedNodes := helpers.LoadNodes("../spec_assets/dummy_two_node_response.json")
			expectedNodesData, err := json.Marshal(expectedNodes)
			Expect(err).ToNot(HaveOccurred())

			server.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("GET", "/api/common/nodes"),
					ghttp.RespondWith(http.StatusOK, expectedNodesData),
				),
			)

			hasVM, err := cpi.HasVM(cpiConfig, metadataInput)
			Expect(err).ToNot(HaveOccurred())
			Expect(hasVM).To(BeTrue())
			Expect(server.ReceivedRequests()).To(HaveLen(1))
		})
	BeforeEach(func() {
		server = ghttp.NewServer()
		serverURL, err := url.Parse(server.URL())
		Expect(err).ToNot(HaveOccurred())
		jsonReader = strings.NewReader(fmt.Sprintf(`{"apiserver":"%s", "agent":{"blobstore": {"provider":"local","some": "options"}, "mbus":"localhost"}, "max_create_vm_attempts":1}`, serverURL.Host))
		cpiConfig, err = config.New(jsonReader, bosh.CpiRequest{})
		Expect(err).ToNot(HaveOccurred())
	})

	AfterEach(func() {
		server.Close()
	})

	Describe("Getting nodes", func() {
		It("return expected nodes' fields", func() {
			expectedNodes := helpers.LoadNodes("../spec_assets/dummy_two_node_response.json")
			expectedNodesData, err := json.Marshal(expectedNodes)
			Expect(err).ToNot(HaveOccurred())
			server.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("GET", "/api/common/nodes"),
					ghttp.RespondWith(http.StatusOK, expectedNodesData),
				),
			)

			nodes, err := rackhdapi.GetNodes(cpiConfig)

			Expect(err).ToNot(HaveOccurred())
			Expect(server.ReceivedRequests()).To(HaveLen(1))
			Expect(nodes).To(Equal(expectedNodes))
		})
	AfterEach(func() {
		server.Close()
	})

	Context("given a disk CID that exists", func() {
		Context("given a disk CID that is not attached", func() {
			It("returns an error", func() {
				jsonInput := []byte(`[
						"valid_vm_cid_1",
						"valid_disk_cid_1"
					]`)
				var extInput bosh.MethodArguments
				err := json.Unmarshal(jsonInput, &extInput)
				Expect(err).ToNot(HaveOccurred())

				expectedNodes := helpers.LoadNodes("../spec_assets/dummy_attached_disk_response.json")
				expectedNodesData, err := json.Marshal(expectedNodes)
				Expect(err).ToNot(HaveOccurred())
				server.AppendHandlers(
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", "/api/common/nodes"),
						ghttp.RespondWith(http.StatusOK, expectedNodesData),
					),
				)

				err = DetachDisk(cpiConfig, extInput)
				Expect(err).To(MatchError("Disk: valid_disk_cid_1 is detached\n"))
				Expect(len(server.ReceivedRequests())).To(Equal(1))
			})
		})
						ghttp.VerifyRequest("GET", fmt.Sprintf("/api/common/nodes/5665a65a0561790005b77b85")),
						ghttp.RespondWith(http.StatusOK, nodeResponse),
					),
				)

				node, err = SelectNodeFromRackHD(cpiConfig, "5665a65a0561790005b77b85", allowFilter)
				Expect(err).ToNot(HaveOccurred())
				Expect(node.ID).To(Equal("5665a65a0561790005b77b85"))
			})
		})
	})

	Describe("randomSelectAvailableNode", func() {
		Context("when all nodes are reserved", func() {
			It("returns an error", func() {
				nodes := helpers.LoadNodes("../spec_assets/dummy_all_reserved_nodes_response.json")

				node0HttpResponse, err := json.Marshal(nodes[0])
				Expect(err).ToNot(HaveOccurred())
				node1HttpResponse, err := json.Marshal(nodes[1])
				Expect(err).ToNot(HaveOccurred())

				server.RouteToHandler("GET", fmt.Sprintf("/api/1.1/nodes/%s/workflows/active", nodes[0].ID),
					ghttp.CombineHandlers(
						ghttp.VerifyRequest("GET", fmt.Sprintf("/api/1.1/nodes/%s/workflows/active", nodes[0].ID)),
						ghttp.RespondWith(http.StatusNoContent, []byte{}),
					),
				)

				server.RouteToHandler("GET", fmt.Sprintf("/api/common/nodes/%s", nodes[0].ID),
					ghttp.CombineHandlers(