func (s *UpstreamSuite) TestUpstreamFromObj(c *C) {
	upstreams := []struct {
		Expected Upstream
		Parse    string
	}{
		{
			Parse: `"http://google.com:5000"`,
			Expected: Upstream{
				Id:      "http://google.com:5000",
				Scheme:  "http",
				Host:    "google.com",
				Port:    5000,
				Metrics: metrics.GetUpstreamMetrics("http_google_com_5000"),
			},
		},
		{
			Parse: `"http://google.com:5000/"`,
			Expected: Upstream{
				Id:      "http://google.com:5000",
				Scheme:  "http",
				Host:    "google.com",
				Port:    5000,
				Metrics: metrics.GetUpstreamMetrics("http_google_com_5000"),
			},
		},
		{
			Parse: `{"scheme": "http", "host": "localhost", "port": 3000}`,
			Expected: Upstream{
				Id:      "http://localhost:3000",
				Scheme:  "http",
				Host:    "localhost",
				Port:    3000,
				Metrics: metrics.GetUpstreamMetrics("http_localhost_3000"),
			},
		},
		{
			Parse: `{"scheme": "https", "host": "localhost", "port": 4000}`,
			Expected: Upstream{
				Id:      "https://localhost:4000",
				Scheme:  "https",
				Host:    "localhost",
				Port:    4000,
				Metrics: metrics.GetUpstreamMetrics("https_localhost_4000"),
			},
		},
	}

	for _, u := range upstreams {
		var value interface{}
		err := json.Unmarshal([]byte(u.Parse), &value)
		c.Assert(err, IsNil)
		parsed, err := NewUpstreamFromObj(value)
		c.Assert(err, IsNil)
		c.Assert(u.Expected, DeepEquals, *parsed)
	}
}
func (s *UpstreamSuite) TestNewUpstreamNoPort(c *C) {
	u, err := NewUpstreamFromString("http://localhost")
	c.Assert(err, IsNil)
	expected := Upstream{
		Id:      "http://localhost:80",
		Scheme:  "http",
		Host:    "localhost",
		Port:    80,
		Metrics: metrics.GetUpstreamMetrics("http_localhost_80"),
	}
	c.Assert(*u, DeepEquals, expected)
}
func NewUpstream(scheme string, host string, port int) (*Upstream, error) {

	if len(scheme) == 0 {
		return nil, fmt.Errorf("Expected scheme")
	}

	if scheme != "http" && scheme != "https" {
		return nil, fmt.Errorf("Unsupported scheme: %s", scheme)
	}

	id := fmt.Sprintf("%s://%s:%d", scheme, host, port)
	metricsId := fmt.Sprintf("%s_%s_%d", scheme, host, port)
	metricsId = strings.Replace(metricsId, ".", "_", -1)
	um := metrics.GetUpstreamMetrics(metricsId)

	return &Upstream{
		Id:      id,
		Scheme:  scheme,
		Host:    host,
		Port:    port,
		Metrics: um,
	}, nil
}
func (s *ForwardSuite) TestForwardSuccess(c *C) {
	commands := []struct {
		Expected *Forward
		Parse    string
	}{
		{
			Parse: `{"upstreams": ["http://localhost:5000", "http://localhost:5001"]}`,
			Expected: &Forward{
				Upstreams: []*Upstream{
					&Upstream{
						Id:      "http://localhost:5000",
						Scheme:  "http",
						Port:    5000,
						Host:    "localhost",
						Metrics: metrics.GetUpstreamMetrics("http_localhost_5000"),
					},
					&Upstream{
						Id:      "http://localhost:5001",
						Scheme:  "http",
						Port:    5001,
						Host:    "localhost",
						Metrics: metrics.GetUpstreamMetrics("http_localhost_5001"),
					},
				},
			},
		},
		{
			Parse: `{"rates": {"$request.ip": "1 req/second"}, "upstreams": ["http://localhost:5000", "http://localhost:5001"]}`,
			Expected: &Forward{
				Rates: map[string][]*Rate{
					"$request.ip": []*Rate{&Rate{Units: 1, Period: time.Second}},
				},
				Upstreams: []*Upstream{
					&Upstream{
						Id:      "http://localhost:5000",
						Scheme:  "http",
						Port:    5000,
						Host:    "localhost",
						Metrics: metrics.GetUpstreamMetrics("http_localhost_5000"),
					},
					&Upstream{
						Id:      "http://localhost:5001",
						Scheme:  "http",
						Port:    5001,
						Host:    "localhost",
						Metrics: metrics.GetUpstreamMetrics("http_localhost_5001"),
					},
				},
			},
		},
		{
			Parse: `{
                  "failover": {"active": true, "codes": [301, 302]},
                  "rates": {
                     "$request.ip": [
                         "1 req/second",
                         {"KB": 8, "period": "hour"}
                  ]},
                  "upstreams": [
                       "http://localhost:5000",
                        {
                           "scheme": "http",
                           "host": "localhost",
                           "port": 5001
                        }
                  ],
                "add_headers": {"N": "v1"},
                "remove_headers": ["M"],
                "rewrite_path": "/new/path"
            }`,
			Expected: &Forward{
				Failover: &Failover{Active: true, Codes: []int{301, 302}},
				Rates: map[string][]*Rate{
					"$request.ip": []*Rate{
						&Rate{Units: 1, Period: time.Second},
						&Rate{Units: 8, UnitType: UnitTypeKilobytes, Period: time.Hour},
					},
				},
				AddHeaders:    http.Header{"N": []string{"v1"}},
				RemoveHeaders: []string{"M"},
				RewritePath:   "/new/path",
				Upstreams: []*Upstream{
					&Upstream{
						Id:      "http://localhost:5000",
						Scheme:  "http",
						Port:    5000,
						Host:    "localhost",
						Metrics: metrics.GetUpstreamMetrics("http_localhost_5000"),
					},
					&Upstream{
						Id:      "http://localhost:5001",
						Scheme:  "http",
						Port:    5001,
						Host:    "localhost",
						Metrics: metrics.GetUpstreamMetrics("http_localhost_5001"),
					},
				},
			},
		},
	}

	for _, cmd := range commands {
		var value interface{}
		err := json.Unmarshal([]byte(cmd.Parse), &value)
		c.Assert(err, IsNil)
		parsed, err := NewCommandFromObj(value)
		c.Assert(err, IsNil)
		c.Assert(parsed, DeepEquals, cmd.Expected)
	}
}