<commit_before>// +build !providerless

/*
Copyright 2018 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package azure

import (
	"testing"
	"strconv"

	"github.com/stretchr/testify/assert"

	v1 "k8s.io/api/core/v1"
	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestIsMasterNode(t *testing.T) {
	if isMasterNode(&v1.Node{}) {
		t.Errorf("Empty node should not be master!")
	}
	if isMasterNode(&v1.Node{
		ObjectMeta: meta.ObjectMeta{
			Labels: map[string]string{
				nodeLabelRole: "worker",
			},
		},
	}) {
		t.Errorf("Node labelled 'worker' should not be master!")
	}
	if !isMasterNode(&v1.Node{
		ObjectMeta: meta.ObjectMeta{
			Labels: map[string]string{
				nodeLabelRole: "master",
			},
		},
	}) {
		t.Errorf("Node should be master!")
	}
}

func TestGetLastSegment(t *testing.T) {
	tests := []struct {
		ID        string
		expected  string
		expectErr bool
	}{
		{
			ID:        "",
			expected:  "",
			expectErr: true,
		},
		{
			ID:        "foo/",
			expected:  "",
			expectErr: true,
		},
		{
			ID:        "foo/bar",
			expected:  "bar",
			expectErr: false,
		},
		{
			ID:        "foo/bar/baz",
			expected:  "baz",
			expectErr: false,
		},
	}

	for _, test := range tests {
		s, e := getLastSegment(test.ID)
		if test.expectErr && e == nil {
			t.Errorf("Expected err, but it was nil")
			continue
		}
		if !test.expectErr && e != nil {
			t.Errorf("Unexpected error: %v", e)
			continue
		}
		if s != test.expected {
			t.Errorf("expected: %s, got %s", test.expected, s)
		}
	}
}

func TestGenerateStorageAccountName(t *testing.T) {
	tests := []struct {
		prefix string
	}{
		{
			prefix: "",
		},
		{
			prefix: "pvc",
		},
		{
			prefix: "1234512345123451234512345",
		},
	}

	for _, test := range tests {
		accountName := generateStorageAccountName(test.prefix)
		if len(accountName) > storageAccountNameMaxLength || len(accountName) < 3 {
			t.Errorf("input prefix: %s, output account name: %s, length not in [3,%d]", test.prefix, accountName, storageAccountNameMaxLength)
		}

		for _, char := range accountName {
			if (char < 'a' || char > 'z') && (char < '0' || char > '9') {
				t.Errorf("input prefix: %s, output account name: %s, there is non-digit or non-letter(%q)", test.prefix, accountName, char)
				break
			}
		}
	}
}

func TestMapLoadBalancerNameToVMSet(t *testing.T) {
	az := getTestCloud()
	az.PrimaryAvailabilitySetName = "primary"

	cases := []struct {
		description   string
		lbName        string
		useStandardLB bool
		clusterName   string
		expectedVMSet string
	}{
		{
			description:   "default external LB should map to primary vmset",
			lbName:        "azure",
			clusterName:   "azure",
			expectedVMSet: "primary",
		},
		{
			description:   "default internal LB should map to primary vmset",
			lbName:        "azure-internal",
			clusterName:   "azure",
			expectedVMSet: "primary",
		},
		{
			description:   "non-default external LB should map to its own vmset",
			lbName:        "azuretest-internal",
			clusterName:   "azure",
			expectedVMSet: "azuretest",
		},
		{
			description:   "non-default internal LB should map to its own vmset",
			lbName:        "azuretest-internal",
			clusterName:   "azure",
			expectedVMSet: "azuretest",
		},
	}

	for _, c := range cases {
		if c.useStandardLB {
			az.Config.LoadBalancerSku = loadBalancerSkuStandard
		} else {
			az.Config.LoadBalancerSku = loadBalancerSkuBasic
		}
		vmset := az.mapLoadBalancerNameToVMSet(c.lbName, c.clusterName)
		assert.Equal(t, c.expectedVMSet, vmset, c.description)
	}
}

func TestGetAzureLoadBalancerName(t *testing.T) {
	az := getTestCloud()
	az.PrimaryAvailabilitySetName = "primary"

	cases := []struct {
		description   string
		vmSet         string
		isInternal    bool
		useStandardLB bool
		clusterName   string
		expected      string
	}{
		{
			description: "default external LB should get primary vmset",
			vmSet:       "primary",
			clusterName: "azure",
			expected:    "azure",
		},
		{
			description: "default internal LB should get primary vmset",
			vmSet:       "primary",
			clusterName: "azure",
			isInternal:  true,
			expected:    "azure-internal",
		},
		{
			description: "non-default external LB should get its own vmset",
			vmSet:       "as",
			clusterName: "azure",
			expected:    "as",
		},
		{
			description: "non-default internal LB should get its own vmset",
			vmSet:       "as",
			clusterName: "azure",
			isInternal:  true,
			expected:    "as-internal",
		},
		{
			description:   "default standard external LB should get cluster name",
			vmSet:         "primary",
			useStandardLB: true,
			clusterName:   "azure",
			expected:      "azure",
		},
		{
			description:   "default standard internal LB should get cluster name",
			vmSet:         "primary",
			useStandardLB: true,
			isInternal:    true,
			clusterName:   "azure",
			expected:      "azure-internal",
		},
		{
			description:   "non-default standard external LB should get cluster-name",
			vmSet:         "as",
			useStandardLB: true,
			clusterName:   "azure",
			expected:      "azure",
		},
		{
			description:   "non-default standard internal LB should get cluster-name",
			vmSet:         "as",
			useStandardLB: true,
			isInternal:    true,
			clusterName:   "azure",
			expected:      "azure-internal",
		},
	}

	for _, c := range cases {
		if c.useStandardLB {
			az.Config.LoadBalancerSku = loadBalancerSkuStandard
		} else {
			az.Config.LoadBalancerSku = loadBalancerSkuBasic
		}
		loadbalancerName := az.getAzureLoadBalancerName(c.clusterName, c.vmSet, c.isInternal)
		assert.Equal(t, c.expected, loadbalancerName, c.description)
	}
}

func TestGetLoadBalancingRuleName(t *testing.T) {
	az := getTestCloud()
	az.PrimaryAvailabilitySetName = "primary"

	svc := &v1.Service{
		ObjectMeta: meta.ObjectMeta{
			Annotations: map[string]string{
				ServiceAnnotationLoadBalancerInternalSubnet: "subnet",
				ServiceAnnotationLoadBalancerInternal:       "true",
			},
			UID: "257b9655-5137-4ad2-b091-ef3f07043ad3",
		},
	}

	cases := []struct {
		description string
		subnetName    string
		isInternal    bool
		useStandardLB bool
		protocol      v1.Protocol
		port          int32
		expected      string
	}{
		{
			description: "internal lb should have subnet name on the rule name",
			subnetName:       "shortsubnet",
			isInternal: true,
			useStandardLB:    true,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-shortsubnet-TCP-9000",
		},
		{
			description: "internal standard lb should have subnet name on the rule name but truncated to 80 charactors",
			subnetName:       "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet",
			isInternal: true,
			useStandardLB:    true,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg-TCP-9000",
		},
		{
			description: "internal basic lb should have subnet name on the rule name but truncated to 80 charactors",
			subnetName:       "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet",
			isInternal: true,
			useStandardLB:    false,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg-TCP-9000",
		},
		{
			description: "external standard lb should not have subnet name on the rule name",
			subnetName:       "shortsubnet",
			isInternal: false,
			useStandardLB:    true,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-TCP-9000",
		},
		{
			description: "external basic lb should not have subnet name on the rule name",
			subnetName:       "shortsubnet",
			isInternal: false,
			useStandardLB:    false,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-TCP-9000",
		},
	}

	for _, c := range cases {
		if c.useStandardLB {
			az.Config.LoadBalancerSku = loadBalancerSkuStandard
		} else {
			az.Config.LoadBalancerSku = loadBalancerSkuBasic
		}
		svc.Annotations[ServiceAnnotationLoadBalancerInternalSubnet] = c.subnetName
		svc.Annotations[ServiceAnnotationLoadBalancerInternal] = strconv.FormatBool(c.isInternal)

		loadbalancerName := az.getLoadBalancerRuleName(svc, c.protocol, c.port)
		assert.Equal(t, c.expected, loadbalancerName, c.description)
	}
}
<commit_msg>fix: add unit tests for truncate long subnet name on lb ip configuration<commit_after>// +build !providerless

/*
Copyright 2018 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package azure

import (
	"testing"
	"strconv"

	"github.com/stretchr/testify/assert"

	v1 "k8s.io/api/core/v1"
	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestIsMasterNode(t *testing.T) {
	if isMasterNode(&v1.Node{}) {
		t.Errorf("Empty node should not be master!")
	}
	if isMasterNode(&v1.Node{
		ObjectMeta: meta.ObjectMeta{
			Labels: map[string]string{
				nodeLabelRole: "worker",
			},
		},
	}) {
		t.Errorf("Node labelled 'worker' should not be master!")
	}
	if !isMasterNode(&v1.Node{
		ObjectMeta: meta.ObjectMeta{
			Labels: map[string]string{
				nodeLabelRole: "master",
			},
		},
	}) {
		t.Errorf("Node should be master!")
	}
}

func TestGetLastSegment(t *testing.T) {
	tests := []struct {
		ID        string
		expected  string
		expectErr bool
	}{
		{
			ID:        "",
			expected:  "",
			expectErr: true,
		},
		{
			ID:        "foo/",
			expected:  "",
			expectErr: true,
		},
		{
			ID:        "foo/bar",
			expected:  "bar",
			expectErr: false,
		},
		{
			ID:        "foo/bar/baz",
			expected:  "baz",
			expectErr: false,
		},
	}

	for _, test := range tests {
		s, e := getLastSegment(test.ID)
		if test.expectErr && e == nil {
			t.Errorf("Expected err, but it was nil")
			continue
		}
		if !test.expectErr && e != nil {
			t.Errorf("Unexpected error: %v", e)
			continue
		}
		if s != test.expected {
			t.Errorf("expected: %s, got %s", test.expected, s)
		}
	}
}

func TestGenerateStorageAccountName(t *testing.T) {
	tests := []struct {
		prefix string
	}{
		{
			prefix: "",
		},
		{
			prefix: "pvc",
		},
		{
			prefix: "1234512345123451234512345",
		},
	}

	for _, test := range tests {
		accountName := generateStorageAccountName(test.prefix)
		if len(accountName) > storageAccountNameMaxLength || len(accountName) < 3 {
			t.Errorf("input prefix: %s, output account name: %s, length not in [3,%d]", test.prefix, accountName, storageAccountNameMaxLength)
		}

		for _, char := range accountName {
			if (char < 'a' || char > 'z') && (char < '0' || char > '9') {
				t.Errorf("input prefix: %s, output account name: %s, there is non-digit or non-letter(%q)", test.prefix, accountName, char)
				break
			}
		}
	}
}

func TestMapLoadBalancerNameToVMSet(t *testing.T) {
	az := getTestCloud()
	az.PrimaryAvailabilitySetName = "primary"

	cases := []struct {
		description   string
		lbName        string
		useStandardLB bool
		clusterName   string
		expectedVMSet string
	}{
		{
			description:   "default external LB should map to primary vmset",
			lbName:        "azure",
			clusterName:   "azure",
			expectedVMSet: "primary",
		},
		{
			description:   "default internal LB should map to primary vmset",
			lbName:        "azure-internal",
			clusterName:   "azure",
			expectedVMSet: "primary",
		},
		{
			description:   "non-default external LB should map to its own vmset",
			lbName:        "azuretest-internal",
			clusterName:   "azure",
			expectedVMSet: "azuretest",
		},
		{
			description:   "non-default internal LB should map to its own vmset",
			lbName:        "azuretest-internal",
			clusterName:   "azure",
			expectedVMSet: "azuretest",
		},
	}

	for _, c := range cases {
		if c.useStandardLB {
			az.Config.LoadBalancerSku = loadBalancerSkuStandard
		} else {
			az.Config.LoadBalancerSku = loadBalancerSkuBasic
		}
		vmset := az.mapLoadBalancerNameToVMSet(c.lbName, c.clusterName)
		assert.Equal(t, c.expectedVMSet, vmset, c.description)
	}
}

func TestGetAzureLoadBalancerName(t *testing.T) {
	az := getTestCloud()
	az.PrimaryAvailabilitySetName = "primary"

	cases := []struct {
		description   string
		vmSet         string
		isInternal    bool
		useStandardLB bool
		clusterName   string
		expected      string
	}{
		{
			description: "default external LB should get primary vmset",
			vmSet:       "primary",
			clusterName: "azure",
			expected:    "azure",
		},
		{
			description: "default internal LB should get primary vmset",
			vmSet:       "primary",
			clusterName: "azure",
			isInternal:  true,
			expected:    "azure-internal",
		},
		{
			description: "non-default external LB should get its own vmset",
			vmSet:       "as",
			clusterName: "azure",
			expected:    "as",
		},
		{
			description: "non-default internal LB should get its own vmset",
			vmSet:       "as",
			clusterName: "azure",
			isInternal:  true,
			expected:    "as-internal",
		},
		{
			description:   "default standard external LB should get cluster name",
			vmSet:         "primary",
			useStandardLB: true,
			clusterName:   "azure",
			expected:      "azure",
		},
		{
			description:   "default standard internal LB should get cluster name",
			vmSet:         "primary",
			useStandardLB: true,
			isInternal:    true,
			clusterName:   "azure",
			expected:      "azure-internal",
		},
		{
			description:   "non-default standard external LB should get cluster-name",
			vmSet:         "as",
			useStandardLB: true,
			clusterName:   "azure",
			expected:      "azure",
		},
		{
			description:   "non-default standard internal LB should get cluster-name",
			vmSet:         "as",
			useStandardLB: true,
			isInternal:    true,
			clusterName:   "azure",
			expected:      "azure-internal",
		},
	}

	for _, c := range cases {
		if c.useStandardLB {
			az.Config.LoadBalancerSku = loadBalancerSkuStandard
		} else {
			az.Config.LoadBalancerSku = loadBalancerSkuBasic
		}
		loadbalancerName := az.getAzureLoadBalancerName(c.clusterName, c.vmSet, c.isInternal)
		assert.Equal(t, c.expected, loadbalancerName, c.description)
	}
}

func TestGetLoadBalancingRuleName(t *testing.T) {
	az := getTestCloud()
	az.PrimaryAvailabilitySetName = "primary"

	svc := &v1.Service{
		ObjectMeta: meta.ObjectMeta{
			Annotations: map[string]string{ 	},
			UID: "257b9655-5137-4ad2-b091-ef3f07043ad3",
		},
	}

	cases := []struct {
		description string
		subnetName    string
		isInternal    bool
		useStandardLB bool
		protocol      v1.Protocol
		port          int32
		expected      string
	}{
		{
			description: "internal lb should have subnet name on the rule name",
			subnetName:       "shortsubnet",
			isInternal: true,
			useStandardLB:    true,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-shortsubnet-TCP-9000",
		},
		{
			description: "internal standard lb should have subnet name on the rule name but truncated to 80 charactors",
			subnetName:       "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet",
			isInternal: true,
			useStandardLB:    true,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg-TCP-9000",
		},
		{
			description: "internal basic lb should have subnet name on the rule name but truncated to 80 charactors",
			subnetName:       "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet",
			isInternal: true,
			useStandardLB:    false,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg-TCP-9000",
		},
		{
			description: "external standard lb should not have subnet name on the rule name",
			subnetName:       "shortsubnet",
			isInternal: false,
			useStandardLB:    true,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-TCP-9000",
		},
		{
			description: "external basic lb should not have subnet name on the rule name",
			subnetName:       "shortsubnet",
			isInternal: false,
			useStandardLB:    false,
			protocol: v1.ProtocolTCP,
			port: 9000,
			expected: "a257b965551374ad2b091ef3f07043ad-TCP-9000",
		},
	}

	for _, c := range cases {
		if c.useStandardLB {
			az.Config.LoadBalancerSku = loadBalancerSkuStandard
		} else {
			az.Config.LoadBalancerSku = loadBalancerSkuBasic
		}
		svc.Annotations[ServiceAnnotationLoadBalancerInternalSubnet] = c.subnetName
		svc.Annotations[ServiceAnnotationLoadBalancerInternal] = strconv.FormatBool(c.isInternal)

		loadbalancerRuleName := az.getLoadBalancerRuleName(svc, c.protocol, c.port)
		assert.Equal(t, c.expected, loadbalancerRuleName, c.description)
	}
}

func TestgetFrontendIPConfigName(t *testing.T) {
	az := getTestCloud()
	az.PrimaryAvailabilitySetName = "primary"

	svc := &v1.Service{
		ObjectMeta: meta.ObjectMeta{
			Annotations: map[string]string{
				ServiceAnnotationLoadBalancerInternalSubnet: "subnet",
				ServiceAnnotationLoadBalancerInternal:       "true",
			},
			UID: "257b9655-5137-4ad2-b091-ef3f07043ad3",
		},
	}

	cases := []struct {
		description string
		subnetName    string
		isInternal    bool
		useStandardLB bool
		expected      string
	}{
		{
			description: "internal lb should have subnet name on the frontend ip configuration name",
			subnetName:       "shortsubnet",
			isInternal: true,
			useStandardLB:    true,
			expected: "a257b965551374ad2b091ef3f07043ad-shortsubnet",
		},
		{
			description: "internal standard lb should have subnet name on the frontend ip configuration name but truncated to 80 charactors",
			subnetName:       "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet",
			isInternal: true,
			useStandardLB:    true,
			expected: "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg",
		},
		{
			description: "internal basic lb should have subnet name on the frontend ip configuration name but truncated to 80 charactors",
			subnetName:       "averylonnnngggnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggggggggggggggggggggggsubet",
			isInternal: true,
			useStandardLB:    false,
			expected: "a257b965551374ad2b091ef3f07043ad-averylonnnngggnnnnnnnnnnnnnnnnnnnnnngg",
		},
		{
			description: "external standard lb should not have subnet name on the frontend ip configuration name",
			subnetName:       "shortsubnet",
			isInternal: false,
			useStandardLB:    true,
			expected: "a257b965551374ad2b091ef3f07043ad",
		},
		{
			description: "external basic lb should not have subnet name on the frontend ip configuration name",
			subnetName:       "shortsubnet",
			isInternal: false,
			useStandardLB:    false,
			expected: "a257b965551374ad2b091ef3f07043ad",
		},
	}

	for _, c := range cases {
		if c.useStandardLB {
			az.Config.LoadBalancerSku = loadBalancerSkuStandard
		} else {
			az.Config.LoadBalancerSku = loadBalancerSkuBasic
		}
		svc.Annotations[ServiceAnnotationLoadBalancerInternalSubnet] = c.subnetName
		svc.Annotations[ServiceAnnotationLoadBalancerInternal] = strconv.FormatBool(c.isInternal)

		loadbalancerName := az.getFrontendIPConfigName(svc)
		assert.Equal(t, c.expected, loadbalancerName, c.description)
	}
}
<|endoftext|>


<commit_before>package rapid

import (
	"strings"
)

type path struct {
	path     string
	method   string
	subPaths map[string]path
}

// Paths - All paths recrusively registered
var Paths map[string]path

// PathHandlers - All path handler's keyed by their path string
var PathHandlers map[string]map[string]func(Connection)

// AddPath - Add route to the map of paths
func AddPath(pathString string, handler func(Connection), method string) {

	pathString = strings.ToLower(pathString)
	pathArr := formatPath(pathString)

	if Paths == nil {
		Paths = make(map[string]path)
		PathHandlers = make(map[string]map[string]func(Connection))
	}

	insertPath(Paths, pathArr, 0, method)
	if PathHandlers[pathString] == nil {
		PathHandlers[pathString] = make(map[string]func(Connection))
	}
	PathHandlers[pathString][method] = handler

}

func formatPath(pathString string) []string {
	pathArr := strings.Split(pathString, "/")
	//loop := true

	for i := 0; i < len(pathArr); i++ {
		if i+1 != len(pathArr) {
			pathArr[i] += "/"
		}
	}

	return pathArr
}

// Insert a path in to the global paths map
func insertPath(paths map[string]path, pathArr []string, index int, method string) {

	singlePath := pathArr[index]
	singlePath = checkPathParams(singlePath)

	if _, ok := paths[singlePath]; ok && index+1 < len(pathArr) {
		insertPath(paths[singlePath].subPaths, pathArr, index+1, method)
	} else {
		emptySlice := make(map[string]path)
		paths[singlePath] = path{strings.Join(pathArr, ""), method, emptySlice}

		if index+1 < len(pathArr) {
			insertPath(paths[singlePath].subPaths, pathArr, index+1, method)
		}

	}

}

// Check if the current path directory is a url parameter
// If it is a param then replace it with  * wild card
func checkPathParams(singlePath string) string {
	if len(singlePath) > 1 {
		if singlePath[0] == ':' {
			if singlePath[len(singlePath)-1] == '/' {
				singlePath = "*/"
			} else {
				singlePath = "*"
			}
		}
	}

	return singlePath
}

// FindCorrectPath - Find the correct path to asscociate with a request url
func FindCorrectPath(path string, method string) string {
	path = strings.ToLower(path)
	pathArr := formatPath(path)
	currentPath := Paths
	lastMatch := "/"

	for i := 0; i < len(pathArr); i++ {
		dir := pathArr[i]

		if _, ok := currentPath[dir]; ok {
			lastMatch = currentPath[dir].path
			currentPath = currentPath[dir].subPaths
		} else if _, ok := currentPath["*"]; ok {
			lastMatch = currentPath["*"].path
			currentPath = currentPath["*"].subPaths
		} else if _, ok := currentPath["*/"]; ok {
			lastMatch = currentPath["*/"].path
			currentPath = currentPath["*/"].subPaths
		} else {
			return "404"
		}
	}

	return lastMatch
}
<commit_msg>Paths are no longer case sensitive while retaining url parameter case sensitivity<commit_after>package rapid

import (
	"strings"
)

type path struct {
	path     string
	method   string
	subPaths map[string]path
}

// Paths - All paths recrusively registered
var Paths map[string]path

// PathHandlers - All path handler's keyed by their path string
var PathHandlers map[string]map[string]func(Connection)

// AddPath - Add route to the map of paths
func AddPath(pathString string, handler func(Connection), method string) {

	pathArr := formatPath(pathString)

	if Paths == nil {
		Paths = make(map[string]path)
		PathHandlers = make(map[string]map[string]func(Connection))
	}

	insertPath(Paths, pathArr, 0, method)
	if PathHandlers[pathString] == nil {
		PathHandlers[pathString] = make(map[string]func(Connection))
	}
	PathHandlers[pathString][method] = handler

}

func formatPath(pathString string) []string {
	pathArr := strings.Split(pathString, "/")
	//loop := true

	for i := 0; i < len(pathArr); i++ {
		if i+1 != len(pathArr) {
			pathArr[i] += "/"
		}
	}

	return pathArr
}

// Insert a path in to the global paths map
func insertPath(paths map[string]path, pathArr []string, index int, method string) {

	singlePath := pathArr[index]
	singlePath = checkPathParams(singlePath)
	singlePath = strings.ToLower(singlePath)

	if _, ok := paths[singlePath]; ok && index+1 < len(pathArr) {
		insertPath(paths[singlePath].subPaths, pathArr, index+1, method)
	} else {
		emptySlice := make(map[string]path)
		paths[singlePath] = path{strings.Join(pathArr, ""), method, emptySlice}

		if index+1 < len(pathArr) {
			insertPath(paths[singlePath].subPaths, pathArr, index+1, method)
		}

	}

}

// Check if the current path directory is a url parameter
// If it is a param then replace it with  * wild card
func checkPathParams(singlePath string) string {
	if len(singlePath) > 1 {
		if singlePath[0] == ':' {
			if singlePath[len(singlePath)-1] == '/' {
				singlePath = "*/"
			} else {
				singlePath = "*"
			}
		}
	}

	return singlePath
}

// FindCorrectPath - Find the correct path to asscociate with a request url
func FindCorrectPath(path string, method string) string {
	path = strings.ToLower(path)
	pathArr := formatPath(path)
	currentPath := Paths
	lastMatch := "/"

	for i := 0; i < len(pathArr); i++ {
		dir := pathArr[i]

		if _, ok := currentPath[dir]; ok {
			lastMatch = currentPath[dir].path
			currentPath = currentPath[dir].subPaths
		} else if _, ok := currentPath["*"]; ok {
			lastMatch = currentPath["*"].path
			currentPath = currentPath["*"].subPaths
		} else if _, ok := currentPath["*/"]; ok {
			lastMatch = currentPath["*/"].path
			currentPath = currentPath["*/"].subPaths
		} else {
			return "404"
		}
	}

	return lastMatch
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"

	"github.com/davecgh/go-spew/spew"
	"github.com/lightningnetwork/lnd/autopilot"
	"github.com/lightningnetwork/lnd/lnwire"
	"github.com/roasbeef/btcd/btcec"
	"github.com/roasbeef/btcd/wire"
	"github.com/roasbeef/btcutil"
)

// chanController is an implementation of the autopilot.ChannelController
// interface that's backed by a running lnd instance.
type chanController struct {
	server *server
}

// OpenChannel opens a channel to a target peer, with a capacity of the
// specified amount. This function should un-block immediately after the
// funding transaction that marks the channel open has been broadcast.
func (c *chanController) OpenChannel(target *btcec.PublicKey,
	amt btcutil.Amount, addrs []net.Addr) error {

	// We can't establish a channel if no addresses were provided for the
	// peer.
	if len(addrs) == 0 {
		return fmt.Errorf("Unable to create channel w/o an active " +
			"address")
	}

	// First, we'll check if we're already connected to the target peer. If
	// not, then we'll need to establish a connection.
	if _, err := c.server.FindPeer(target); err != nil {
		// TODO(roasbeef): try teach addr

		atplLog.Tracef("Connecting to %x to auto-create channel: ",
			target.SerializeCompressed())

		lnAddr := &lnwire.NetAddress{
			IdentityKey: target,
			ChainNet:    activeNetParams.Net,
		}

		// We'll attempt to successively connect to each of the
		// advertised IP addresses until we've either exhausted the
		// advertised IP addresses, or have made a connection.
		var connected bool
		for _, addr := range addrs {
			// If the address doesn't already have a port, then
			// we'll assume the current default port.
			tcpAddr, ok := addr.(*net.TCPAddr)
			if !ok {
				return fmt.Errorf("TCP address required instead "+
					"have %T", addr)
			}
			if tcpAddr.Port == 0 {
				tcpAddr.Port = defaultPeerPort
			}

			lnAddr.Address = tcpAddr

			// TODO(roasbeef): make perm connection in server after
			// chan open?
			err := c.server.ConnectToPeer(lnAddr, false)
			if err != nil {
				// If we weren't able to connect to the peer,
				// then we'll move onto the next.
				continue
			}

			connected = true
			break
		}

		// If we weren't able to establish a connection at all, then
		// we'll error out.
		if !connected {
			return fmt.Errorf("Unable to connect to %x",
				target.SerializeCompressed())
		}
	}

	// With the connection established, we'll now establish our connection
	// to the target peer, waiting for the first update before we exit.
	feePerWeight, err := c.server.cc.feeEstimator.EstimateFeePerWeight(3)
	if err != nil {
		return err
	}
	updateStream, errChan := c.server.OpenChannel(-1, target, amt, 0,
		feePerWeight, false)

	select {
	case err := <-errChan:
		return err
	case <-updateStream:
		return nil
	case <-c.server.quit:
		return nil
	}
}

func (c *chanController) CloseChannel(chanPoint *wire.OutPoint) error {
	return nil
}
func (c *chanController) SpliceIn(chanPoint *wire.OutPoint,
	amt btcutil.Amount) (*autopilot.Channel, error) {
	return nil, nil
}
func (c *chanController) SpliceOut(chanPoint *wire.OutPoint,
	amt btcutil.Amount) (*autopilot.Channel, error) {
	return nil, nil
}

// A compile time assertion to ensure chanController meets the
// autopilot.ChannelController interface.
var _ autopilot.ChannelController = (*chanController)(nil)

// initAutoPilot initializes a new autopilot.Agent instance based on the passed
// configuration struct. All interfaces needed to drive the pilot will be
// registered and launched.
func initAutoPilot(svr *server, cfg *autoPilotConfig) (*autopilot.Agent, error) {
	atplLog.Infof("Instantiating autopilot with cfg: %v", spew.Sdump(cfg))

	// First, we'll create the preferential attachment heuristic,
	// initialized with the passed auto pilot configuration parameters.
	//
	// TODO(roasbeef): switch here to dispatch specified heuristic
	minChanSize := svr.cc.wallet.Cfg.DefaultConstraints.DustLimit * 5
	prefAttachment := autopilot.NewConstrainedPrefAttachment(
		minChanSize, maxFundingAmount,
		uint16(cfg.MaxChannels), cfg.Allocation,
	)

	// With the heuristic itself created, we can now populate the remainder
	// of the items that the autopilot agent needs to perform its duties.
	self := svr.identityPriv.PubKey()
	pilotCfg := autopilot.Config{
		Self:           self,
		Heuristic:      prefAttachment,
		ChanController: &chanController{svr},
		WalletBalance: func() (btcutil.Amount, error) {
			return svr.cc.wallet.ConfirmedBalance(1, true)
		},
		Graph: autopilot.ChannelGraphFromDatabase(svr.chanDB.ChannelGraph()),
	}

	// Next, we'll fetch the current state of open channels from the
	// database to use as initial state for the auto-pilot agent.
	activeChannels, err := svr.chanDB.FetchAllChannels()
	if err != nil {
		return nil, err
	}
	initialChanState := make([]autopilot.Channel, len(activeChannels))
	for i, channel := range activeChannels {
		initialChanState[i] = autopilot.Channel{
			ChanID:   channel.ShortChanID,
			Capacity: channel.Capacity,
			Node:     autopilot.NewNodeID(channel.IdentityPub),
		}
	}

	// Now that we have all the initial dependencies, we can create the
	// auto-pilot instance itself.
	pilot, err := autopilot.New(pilotCfg, initialChanState)
	if err != nil {
		return nil, err
	}

	// Finally, we'll need to subscribe to two things: incoming
	// transactions that modify the wallet's balance, and also any graph
	// topology updates.
	txnSubscription, err := svr.cc.wallet.SubscribeTransactions()
	if err != nil {
		return nil, err
	}
	graphSubscription, err := svr.chanRouter.SubscribeTopology()
	if err != nil {
		return nil, err
	}

	// We'll launch a goroutine to provide the agent with notifications
	// whenever the balance of the wallet changes.
	svr.wg.Add(1)
	go func() {
		defer txnSubscription.Cancel()
		defer svr.wg.Done()

		for {
			select {
			case txnUpdate := <-txnSubscription.ConfirmedTransactions():
				pilot.OnBalanceChange(txnUpdate.Value)
			case <-svr.quit:
				return
			}
		}

	}()

	// We'll also launch a goroutine to provide the agent with
	// notifications for when the graph topology controlled by the node
	// changes.
	svr.wg.Add(1)
	go func() {
		defer graphSubscription.Cancel()
		defer svr.wg.Done()

		for {
			select {
			case topChange, ok := <-graphSubscription.TopologyChanges:
				// If the router is shutting down, then we will
				// as well.
				if !ok {
					return
				}

				for _, edgeUpdate := range topChange.ChannelEdgeUpdates {
					// If this isn't an advertisement by
					// the backing lnd node, then we'll
					// continue as we only want to add
					// channels that we've created
					// ourselves.
					if !edgeUpdate.AdvertisingNode.IsEqual(self) {
						continue
					}

					// If this is indeed a channel we
					// opened, then we'll convert it to the
					// autopilot.Channel format, and notify
					// the pilot of the new channel.
					chanNode := autopilot.NewNodeID(
						edgeUpdate.ConnectingNode,
					)
					chanID := lnwire.NewShortChanIDFromInt(
						edgeUpdate.ChanID,
					)
					edge := autopilot.Channel{
						ChanID:   chanID,
						Capacity: edgeUpdate.Capacity,
						Node:     chanNode,
					}
					pilot.OnChannelOpen(edge)
				}

				// For each closed closed channel, we'll obtain
				// the chanID of the closed channel and send it
				// to the pilot.
				for _, chanClose := range topChange.ClosedChannels {
					chanID := lnwire.NewShortChanIDFromInt(
						chanClose.ChanID,
					)

					pilot.OnChannelClose(chanID)
				}

			case <-svr.quit:
				return
			}
		}
	}()

	return pilot, nil
}
<commit_msg>pilot: fix goroutine leak by also draining UnconfirmedTransactions notifications<commit_after>package main

import (
	"fmt"
	"net"

	"github.com/davecgh/go-spew/spew"
	"github.com/lightningnetwork/lnd/autopilot"
	"github.com/lightningnetwork/lnd/lnwire"
	"github.com/roasbeef/btcd/btcec"
	"github.com/roasbeef/btcd/wire"
	"github.com/roasbeef/btcutil"
)

// chanController is an implementation of the autopilot.ChannelController
// interface that's backed by a running lnd instance.
type chanController struct {
	server *server
}

// OpenChannel opens a channel to a target peer, with a capacity of the
// specified amount. This function should un-block immediately after the
// funding transaction that marks the channel open has been broadcast.
func (c *chanController) OpenChannel(target *btcec.PublicKey,
	amt btcutil.Amount, addrs []net.Addr) error {

	// We can't establish a channel if no addresses were provided for the
	// peer.
	if len(addrs) == 0 {
		return fmt.Errorf("Unable to create channel w/o an active " +
			"address")
	}

	// First, we'll check if we're already connected to the target peer. If
	// not, then we'll need to establish a connection.
	if _, err := c.server.FindPeer(target); err != nil {
		// TODO(roasbeef): try teach addr

		atplLog.Tracef("Connecting to %x to auto-create channel: ",
			target.SerializeCompressed())

		lnAddr := &lnwire.NetAddress{
			IdentityKey: target,
			ChainNet:    activeNetParams.Net,
		}

		// We'll attempt to successively connect to each of the
		// advertised IP addresses until we've either exhausted the
		// advertised IP addresses, or have made a connection.
		var connected bool
		for _, addr := range addrs {
			// If the address doesn't already have a port, then
			// we'll assume the current default port.
			tcpAddr, ok := addr.(*net.TCPAddr)
			if !ok {
				return fmt.Errorf("TCP address required instead "+
					"have %T", addr)
			}
			if tcpAddr.Port == 0 {
				tcpAddr.Port = defaultPeerPort
			}

			lnAddr.Address = tcpAddr

			// TODO(roasbeef): make perm connection in server after
			// chan open?
			err := c.server.ConnectToPeer(lnAddr, false)
			if err != nil {
				// If we weren't able to connect to the peer,
				// then we'll move onto the next.
				continue
			}

			connected = true
			break
		}

		// If we weren't able to establish a connection at all, then
		// we'll error out.
		if !connected {
			return fmt.Errorf("Unable to connect to %x",
				target.SerializeCompressed())
		}
	}

	// With the connection established, we'll now establish our connection
	// to the target peer, waiting for the first update before we exit.
	feePerWeight, err := c.server.cc.feeEstimator.EstimateFeePerWeight(3)
	if err != nil {
		return err
	}
	updateStream, errChan := c.server.OpenChannel(-1, target, amt, 0,
		feePerWeight, false)

	select {
	case err := <-errChan:
		return err
	case <-updateStream:
		return nil
	case <-c.server.quit:
		return nil
	}
}

func (c *chanController) CloseChannel(chanPoint *wire.OutPoint) error {
	return nil
}
func (c *chanController) SpliceIn(chanPoint *wire.OutPoint,
	amt btcutil.Amount) (*autopilot.Channel, error) {
	return nil, nil
}
func (c *chanController) SpliceOut(chanPoint *wire.OutPoint,
	amt btcutil.Amount) (*autopilot.Channel, error) {
	return nil, nil
}

// A compile time assertion to ensure chanController meets the
// autopilot.ChannelController interface.
var _ autopilot.ChannelController = (*chanController)(nil)

// initAutoPilot initializes a new autopilot.Agent instance based on the passed
// configuration struct. All interfaces needed to drive the pilot will be
// registered and launched.
func initAutoPilot(svr *server, cfg *autoPilotConfig) (*autopilot.Agent, error) {
	atplLog.Infof("Instantiating autopilot with cfg: %v", spew.Sdump(cfg))

	// First, we'll create the preferential attachment heuristic,
	// initialized with the passed auto pilot configuration parameters.
	//
	// TODO(roasbeef): switch here to dispatch specified heuristic
	minChanSize := svr.cc.wallet.Cfg.DefaultConstraints.DustLimit * 5
	prefAttachment := autopilot.NewConstrainedPrefAttachment(
		minChanSize, maxFundingAmount,
		uint16(cfg.MaxChannels), cfg.Allocation,
	)

	// With the heuristic itself created, we can now populate the remainder
	// of the items that the autopilot agent needs to perform its duties.
	self := svr.identityPriv.PubKey()
	pilotCfg := autopilot.Config{
		Self:           self,
		Heuristic:      prefAttachment,
		ChanController: &chanController{svr},
		WalletBalance: func() (btcutil.Amount, error) {
			return svr.cc.wallet.ConfirmedBalance(1, true)
		},
		Graph: autopilot.ChannelGraphFromDatabase(svr.chanDB.ChannelGraph()),
	}

	// Next, we'll fetch the current state of open channels from the
	// database to use as initial state for the auto-pilot agent.
	activeChannels, err := svr.chanDB.FetchAllChannels()
	if err != nil {
		return nil, err
	}
	initialChanState := make([]autopilot.Channel, len(activeChannels))
	for i, channel := range activeChannels {
		initialChanState[i] = autopilot.Channel{
			ChanID:   channel.ShortChanID,
			Capacity: channel.Capacity,
			Node:     autopilot.NewNodeID(channel.IdentityPub),
		}
	}

	// Now that we have all the initial dependencies, we can create the
	// auto-pilot instance itself.
	pilot, err := autopilot.New(pilotCfg, initialChanState)
	if err != nil {
		return nil, err
	}

	// Finally, we'll need to subscribe to two things: incoming
	// transactions that modify the wallet's balance, and also any graph
	// topology updates.
	txnSubscription, err := svr.cc.wallet.SubscribeTransactions()
	if err != nil {
		return nil, err
	}
	graphSubscription, err := svr.chanRouter.SubscribeTopology()
	if err != nil {
		return nil, err
	}

	// We'll launch a goroutine to provide the agent with notifications
	// whenever the balance of the wallet changes.
	svr.wg.Add(1)
	go func() {
		defer txnSubscription.Cancel()
		defer svr.wg.Done()

		for {
			select {
			case txnUpdate := <-txnSubscription.ConfirmedTransactions():
				pilot.OnBalanceChange(txnUpdate.Value)
			case <-svr.quit:
				return
			}
		}

	}()
	go func() {
		defer txnSubscription.Cancel()
		defer svr.wg.Done()

		for {
			select {
			// We won't act upon new unconfirmed transaction, as
			// we'll only use confirmed outputs when funding.
			// However, we will still drain this request in order
			// to avoid goroutine leaks, and ensure we promptly
			// read from the channel if available.
			case <-txnSubscription.UnconfirmedTransactions():
			case <-svr.quit:
				return
			}
		}

	}()

	// We'll also launch a goroutine to provide the agent with
	// notifications for when the graph topology controlled by the node
	// changes.
	svr.wg.Add(1)
	go func() {
		defer graphSubscription.Cancel()
		defer svr.wg.Done()

		for {
			select {
			case topChange, ok := <-graphSubscription.TopologyChanges:
				// If the router is shutting down, then we will
				// as well.
				if !ok {
					return
				}

				for _, edgeUpdate := range topChange.ChannelEdgeUpdates {
					// If this isn't an advertisement by
					// the backing lnd node, then we'll
					// continue as we only want to add
					// channels that we've created
					// ourselves.
					if !edgeUpdate.AdvertisingNode.IsEqual(self) {
						continue
					}

					// If this is indeed a channel we
					// opened, then we'll convert it to the
					// autopilot.Channel format, and notify
					// the pilot of the new channel.
					chanNode := autopilot.NewNodeID(
						edgeUpdate.ConnectingNode,
					)
					chanID := lnwire.NewShortChanIDFromInt(
						edgeUpdate.ChanID,
					)
					edge := autopilot.Channel{
						ChanID:   chanID,
						Capacity: edgeUpdate.Capacity,
						Node:     chanNode,
					}
					pilot.OnChannelOpen(edge)
				}

				// For each closed closed channel, we'll obtain
				// the chanID of the closed channel and send it
				// to the pilot.
				for _, chanClose := range topChange.ClosedChannels {
					chanID := lnwire.NewShortChanIDFromInt(
						chanClose.ChanID,
					)

					pilot.OnChannelClose(chanID)
				}

			case <-svr.quit:
				return
			}
		}
	}()

	return pilot, nil
}
<|endoftext|>


<commit_before>package linkedql

import (
	"context"

	"github.com/cayleygraph/cayley/graph/iterator"
	"github.com/cayleygraph/cayley/graph/refs"
	"github.com/cayleygraph/cayley/query/path"
)

// ValueIterator is an iterator of values from the graph.
type ValueIterator struct {
	namer   refs.Namer
	path    *path.Path
	scanner iterator.Scanner
}

// NewValueIterator returns a new ValueIterator for a path and namer.
func NewValueIterator(p *path.Path, namer refs.Namer) *ValueIterator {
	return &ValueIterator{namer, p, nil}
}

// Next implements query.Iterator.
func (it *ValueIterator) Next(ctx context.Context) bool {
	if it.scanner == nil {
		it.scanner = it.path.BuildIterator(ctx).Iterate()
	}
	return it.scanner.Next(ctx)
}

// Result implements query.Iterator.
func (it *ValueIterator) Result() interface{} {
	if it.scanner == nil {
		return nil
	}
	return it.namer.NameOf(it.scanner.Result())
}

// Err implements query.Iterator.
func (it *ValueIterator) Err() error {
	if it.scanner == nil {
		return nil
	}
	return it.scanner.Err()
}

// Close implements query.Iterator.
func (it *ValueIterator) Close() error {
	if it.scanner == nil {
		return nil
	}
	return it.scanner.Close()
}
<commit_msg>linkedql: Corrected syntax in value_iterator<commit_after>package linkedql

import (
	"context"

	"github.com/cayleygraph/cayley/graph/iterator"
	"github.com/cayleygraph/cayley/graph/refs"
	"github.com/cayleygraph/cayley/query/path"
)

// ValueIterator is an iterator of values from the graph.
type ValueIterator struct {
	namer   refs.Namer
	path    *path.Path
	scanner iterator.Scanner
}

// NewValueIterator returns a new ValueIterator for a path and namer.
func NewValueIterator(p *path.Path, namer refs.Namer) *ValueIterator {
	return &ValueIterator{namer: namer, path: p}
}

// Next implements query.Iterator.
func (it *ValueIterator) Next(ctx context.Context) bool {
	if it.scanner == nil {
		it.scanner = it.path.BuildIterator(ctx).Iterate()
	}
	return it.scanner.Next(ctx)
}

// Result implements query.Iterator.
func (it *ValueIterator) Result() interface{} {
	if it.scanner == nil {
		return nil
	}
	return it.namer.NameOf(it.scanner.Result())
}

// Err implements query.Iterator.
func (it *ValueIterator) Err() error {
	if it.scanner == nil {
		return nil
	}
	return it.scanner.Err()
}

// Close implements query.Iterator.
func (it *ValueIterator) Close() error {
	if it.scanner == nil {
		return nil
	}
	return it.scanner.Close()
}
<|endoftext|>


<commit_before>package builder

import (
	"github.com/blablacar/cnt/cnt"
	"github.com/blablacar/cnt/utils"
	"strings"
)

func (aci *Aci) Push() {
	if cnt.Home.Config.Push.Type == "" {
		panic("Can't push, push is not configured in cnt global configuration file")
	}

	aci.CheckBuilt()
	if aci.args.Test {
		aci.args.Test = false
		aci.Test()
	}

	aci.tarAci(true)

	im := utils.ExtractManifestFromAci(aci.target + PATH_IMAGE_ACI_ZIP)
	val, _ := im.Labels.Get("version")
	if err := utils.ExecCmd("curl", "-f", "-i",
		"-F", "r=releases",
		"-F", "hasPom=false",
		"-F", "e=aci",
		"-F", "g=com.blablacar.aci.linux.amd64",
		"-F", "p=aci",
		"-F", "v="+val,
		"-F", "a="+strings.Split(string(im.Name), "/")[1],
		"-F", "file=@"+aci.target+PATH_IMAGE_ACI_ZIP,
		"-u", cnt.Home.Config.Push.Username+":"+cnt.Home.Config.Push.Password,
		cnt.Home.Config.Push.Url+"/service/local/artifact/maven/content"); err != nil {
		panic("Cannot push aci" + err.Error())
	}
}
<commit_msg>[#99] add info on upload<commit_after>package builder

import (
	"github.com/blablacar/cnt/cnt"
	"github.com/blablacar/cnt/utils"
	"github.com/n0rad/go-erlog/logs"
	"strings"
)

func (aci *Aci) Push() {
	if cnt.Home.Config.Push.Type == "" {
		panic("Can't push, push is not configured in cnt global configuration file")
	}

	aci.CheckBuilt()
	if aci.args.Test {
		aci.args.Test = false
		aci.Test()
	}

	logs.WithF(aci.fields).Info("Gzipping aci before upload")
	aci.tarAci(true)

	logs.WithF(aci.fields).Info("Uploading aci")
	im := utils.ExtractManifestFromAci(aci.target + PATH_IMAGE_ACI_ZIP)
	val, _ := im.Labels.Get("version")
	if err := utils.ExecCmd("curl", "-f", "-i",
		"-F", "r=releases",
		"-F", "hasPom=false",
		"-F", "e=aci",
		"-F", "g=com.blablacar.aci.linux.amd64",
		"-F", "p=aci",
		"-F", "v="+val,
		"-F", "a="+strings.Split(string(im.Name), "/")[1],
		"-F", "file=@"+aci.target+PATH_IMAGE_ACI_ZIP,
		"-u", cnt.Home.Config.Push.Username+":"+cnt.Home.Config.Push.Password,
		cnt.Home.Config.Push.Url+"/service/local/artifact/maven/content"); err != nil {
		logs.WithEF(err, aci.fields).Error("Failed to push aci")
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"os"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/shield"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSShieldProtectionGlobalAccelerate(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	globalAcceleratorConfig := fmt.Sprintf(testAccShieldProtectionGlobalAcceleratorConfig, rName)
	var providers []*schema.Provider

	resource.Test(t, resource.TestCase{
		PreCheck:          func() { testAccPreCheck(t) },
		ProviderFactories: testAccProviderFactories(&providers),
		CheckDestroy:      testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: globalAcceleratorConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}
func TestAccAWSShieldProtectionElasticIPAddress(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	elasticIPAddressConfig := fmt.Sprintf(testAccShieldProtectionElasticIPAddressConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: elasticIPAddressConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionAlb(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	albConfig := fmt.Sprintf(testAccShieldProtectionAlbConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: albConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}
func TestAccAWSShieldProtectionElb(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	elbConfig := fmt.Sprintf(testAccShieldProtectionElbConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: elbConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionCloudfront(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	cloudfrontConfig := fmt.Sprintf(testAccShieldProtectionCloudfrontConfig, rName, testAccShieldProtectionCloudfrontRetainConfig())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: cloudfrontConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionRoute53(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	route53Config := fmt.Sprintf(testAccShieldProtectionRoute53HostedZoneConfig, rName)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: route53Config,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtection_importBasic(t *testing.T) {
	resourceName := "aws_shield_protection.acctest"
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	elasticIPAddressConfig := fmt.Sprintf(testAccShieldProtectionElasticIPAddressConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: elasticIPAddressConfig,
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckAWSShieldProtectionDestroy(s *terraform.State) error {
	shieldconn := testAccProvider.Meta().(*AWSClient).shieldconn

	for _, rs := range s.RootModule().Resources {

		if rs.Type != "aws_shield_protection" {
			continue
		}

		input := &shield.DescribeProtectionInput{
			ProtectionId: aws.String(rs.Primary.ID),
		}

		resp, err := shieldconn.DescribeProtection(input)
		if err == nil {
			if len(*resp.Protection.Id) > 0 && *resp.Protection.Id == rs.Primary.ID {
				return fmt.Errorf("The Shield protection with ID %v still exists", rs.Primary.ID)
			}
		}
	}

	return nil
}

func testAccCheckAWSShieldProtectionExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		_, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		return nil
	}
}

// Set the environment variable TF_TEST_CLOUDFRONT_RETAIN
// when doing manual tests so that the test is not waiting for
// the distribution to be removed completely.
func testAccShieldProtectionCloudfrontRetainConfig() string {
	if _, ok := os.LookupEnv("TF_TEST_CLOUDFRONT_RETAIN"); ok {
		return "retain_on_delete = true"
	}
	return ""
}

var testAccShieldProtectionRoute53HostedZoneConfig = `
variable "name" {
  default = "%s"
}

resource "aws_route53_zone" "acctest" {
  name    = "${var.name}.com."
  comment = "Terraform Acceptance Tests"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "arn:aws:route53:::hostedzone/${aws_route53_zone.acctest.zone_id}"
}
`

var testAccShieldProtectionElbConfig = `
data "aws_availability_zones" "available" {}

variable "subnets" {
  default = ["10.0.1.0/24", "10.0.2.0/24"]
  type    = "list"
}

variable "name" {
  default = "%s"
}

resource "aws_vpc" "acctest" {
  cidr_block = "10.0.0.0/16"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_subnet" "acctest" {
  count                   = 2
  vpc_id                  = "${aws_vpc.acctest.id}"
  cidr_block              = "${element(var.subnets, count.index)}"
  map_public_ip_on_launch = true
  availability_zone       = "${element(data.aws_availability_zones.available.names, count.index)}"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

}
resource "aws_elb" "acctest" {
  name = "${var.name}"
  #availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
  subnets            = ["${aws_subnet.acctest.*.id[0]}", "${aws_subnet.acctest.*.id[1]}"]
  internal           = true

  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

  cross_zone_load_balancing = true
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_elb.acctest.arn}"
}
`

var testAccShieldProtectionAlbConfig = `
data "aws_availability_zones" "available" {}

variable "subnets" {
  default = ["10.0.1.0/24", "10.0.2.0/24"]
  type    = "list"
}

variable "name" {
  default = "%s"
}

resource "aws_lb" "acctest" {
  name            = "${var.name}"
  internal        = true
  security_groups = ["${aws_security_group.acctest.id}"]
  subnets         = ["${aws_subnet.acctest.*.id[0]}", "${aws_subnet.acctest.*.id[1]}"]

  idle_timeout               = 30
  enable_deletion_protection = false

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_vpc" "acctest" {
  cidr_block = "10.0.0.0/16"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_subnet" "acctest" {
  count                   = 2
  vpc_id                  = "${aws_vpc.acctest.id}"
  cidr_block              = "${element(var.subnets, count.index)}"
  map_public_ip_on_launch = true
  availability_zone       = "${element(data.aws_availability_zones.available.names, count.index)}"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

}

resource "aws_security_group" "acctest" {
  name        = "${var.name}"
  description = "acctest"
  vpc_id      = "${aws_vpc.acctest.id}"

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_lb.acctest.arn}"
}
`

var testAccShieldProtectionCloudfrontConfig = `
variable "name" {
  default = "%s"
}

resource "aws_cloudfront_distribution" "acctest" {
  origin {
    custom_origin_config = {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"

      origin_ssl_protocols = [
        "TLSv1",
        "TLSv1.1",
        "TLSv1.2",
      ]
    }

    # This is a fake origin and it's set to this name to indicate that.
    domain_name = "${var.name}.com"
    origin_id   = "acctest"
  }

  enabled         = true
  is_ipv6_enabled = true
  comment         = "acctest"

  default_cache_behavior {

    allowed_methods  = ["HEAD", "DELETE", "POST", "GET", "OPTIONS", "PUT", "PATCH"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "acctest"

    forwarded_values {
      query_string = false
      headers      = ["*"]

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  %s
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_cloudfront_distribution.acctest.arn}"
}
`

var testAccShieldProtectionElasticIPAddressConfig = `
variable "name" {
  default = "%s"
}

data "aws_availability_zones" "available" {}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

resource "aws_eip" "acctest" {
  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "arn:aws:ec2:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:eip-allocation/${aws_eip.acctest.id}"
}
`

var testAccShieldProtectionGlobalAcceleratorConfig = `
provider "aws" {
  region = "us-west-2"
  alias  = "globalaccelerator"
}

variable "name" {
  default = "%s"
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_globalaccelerator_accelerator.acctest.id}"
}

resource "aws_globalaccelerator_accelerator" "acctest" {
  provider        = "aws.globalaccelerator"
  name            = "${var.name}"
  ip_address_type = "IPV4"
  enabled         = true
}
`
<commit_msg>add spaces between functions for consistency.<commit_after>package aws

import (
	"fmt"
	"os"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/shield"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSShieldProtectionGlobalAccelerate(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	globalAcceleratorConfig := fmt.Sprintf(testAccShieldProtectionGlobalAcceleratorConfig, rName)
	var providers []*schema.Provider

	resource.Test(t, resource.TestCase{
		PreCheck:          func() { testAccPreCheck(t) },
		ProviderFactories: testAccProviderFactories(&providers),
		CheckDestroy:      testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: globalAcceleratorConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionElasticIPAddress(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	elasticIPAddressConfig := fmt.Sprintf(testAccShieldProtectionElasticIPAddressConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: elasticIPAddressConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionAlb(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	albConfig := fmt.Sprintf(testAccShieldProtectionAlbConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: albConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionElb(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	elbConfig := fmt.Sprintf(testAccShieldProtectionElbConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: elbConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionCloudfront(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	cloudfrontConfig := fmt.Sprintf(testAccShieldProtectionCloudfrontConfig, rName, testAccShieldProtectionCloudfrontRetainConfig())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: cloudfrontConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtectionRoute53(t *testing.T) {
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	route53Config := fmt.Sprintf(testAccShieldProtectionRoute53HostedZoneConfig, rName)
	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: route53Config,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSShieldProtectionExists("aws_shield_protection.acctest"),
				),
			},
		},
	})
}

func TestAccAWSShieldProtection_importBasic(t *testing.T) {
	resourceName := "aws_shield_protection.acctest"
	rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
	elasticIPAddressConfig := fmt.Sprintf(testAccShieldProtectionElasticIPAddressConfig, rName)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSShieldProtectionDestroy,
		Steps: []resource.TestStep{
			{
				Config: elasticIPAddressConfig,
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccCheckAWSShieldProtectionDestroy(s *terraform.State) error {
	shieldconn := testAccProvider.Meta().(*AWSClient).shieldconn

	for _, rs := range s.RootModule().Resources {

		if rs.Type != "aws_shield_protection" {
			continue
		}

		input := &shield.DescribeProtectionInput{
			ProtectionId: aws.String(rs.Primary.ID),
		}

		resp, err := shieldconn.DescribeProtection(input)
		if err == nil {
			if len(*resp.Protection.Id) > 0 && *resp.Protection.Id == rs.Primary.ID {
				return fmt.Errorf("The Shield protection with ID %v still exists", rs.Primary.ID)
			}
		}
	}

	return nil
}

func testAccCheckAWSShieldProtectionExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		_, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		return nil
	}
}

// Set the environment variable TF_TEST_CLOUDFRONT_RETAIN
// when doing manual tests so that the test is not waiting for
// the distribution to be removed completely.
func testAccShieldProtectionCloudfrontRetainConfig() string {
	if _, ok := os.LookupEnv("TF_TEST_CLOUDFRONT_RETAIN"); ok {
		return "retain_on_delete = true"
	}
	return ""
}

var testAccShieldProtectionRoute53HostedZoneConfig = `
variable "name" {
  default = "%s"
}

resource "aws_route53_zone" "acctest" {
  name    = "${var.name}.com."
  comment = "Terraform Acceptance Tests"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "arn:aws:route53:::hostedzone/${aws_route53_zone.acctest.zone_id}"
}
`

var testAccShieldProtectionElbConfig = `
data "aws_availability_zones" "available" {}

variable "subnets" {
  default = ["10.0.1.0/24", "10.0.2.0/24"]
  type    = "list"
}

variable "name" {
  default = "%s"
}

resource "aws_vpc" "acctest" {
  cidr_block = "10.0.0.0/16"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_subnet" "acctest" {
  count                   = 2
  vpc_id                  = "${aws_vpc.acctest.id}"
  cidr_block              = "${element(var.subnets, count.index)}"
  map_public_ip_on_launch = true
  availability_zone       = "${element(data.aws_availability_zones.available.names, count.index)}"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

}
resource "aws_elb" "acctest" {
  name = "${var.name}"
  #availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
  subnets            = ["${aws_subnet.acctest.*.id[0]}", "${aws_subnet.acctest.*.id[1]}"]
  internal           = true

  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

  cross_zone_load_balancing = true
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_elb.acctest.arn}"
}
`

var testAccShieldProtectionAlbConfig = `
data "aws_availability_zones" "available" {}

variable "subnets" {
  default = ["10.0.1.0/24", "10.0.2.0/24"]
  type    = "list"
}

variable "name" {
  default = "%s"
}

resource "aws_lb" "acctest" {
  name            = "${var.name}"
  internal        = true
  security_groups = ["${aws_security_group.acctest.id}"]
  subnets         = ["${aws_subnet.acctest.*.id[0]}", "${aws_subnet.acctest.*.id[1]}"]

  idle_timeout               = 30
  enable_deletion_protection = false

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_vpc" "acctest" {
  cidr_block = "10.0.0.0/16"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_subnet" "acctest" {
  count                   = 2
  vpc_id                  = "${aws_vpc.acctest.id}"
  cidr_block              = "${element(var.subnets, count.index)}"
  map_public_ip_on_launch = true
  availability_zone       = "${element(data.aws_availability_zones.available.names, count.index)}"

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

}

resource "aws_security_group" "acctest" {
  name        = "${var.name}"
  description = "acctest"
  vpc_id      = "${aws_vpc.acctest.id}"

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_lb.acctest.arn}"
}
`

var testAccShieldProtectionCloudfrontConfig = `
variable "name" {
  default = "%s"
}

resource "aws_cloudfront_distribution" "acctest" {
  origin {
    custom_origin_config = {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"

      origin_ssl_protocols = [
        "TLSv1",
        "TLSv1.1",
        "TLSv1.2",
      ]
    }

    # This is a fake origin and it's set to this name to indicate that.
    domain_name = "${var.name}.com"
    origin_id   = "acctest"
  }

  enabled         = true
  is_ipv6_enabled = true
  comment         = "acctest"

  default_cache_behavior {

    allowed_methods  = ["HEAD", "DELETE", "POST", "GET", "OPTIONS", "PUT", "PATCH"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "acctest"

    forwarded_values {
      query_string = false
      headers      = ["*"]

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  tags {
    foo  = "bar"
    Name = "${var.name}"
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  %s
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_cloudfront_distribution.acctest.arn}"
}
`

var testAccShieldProtectionElasticIPAddressConfig = `
variable "name" {
  default = "%s"
}

data "aws_availability_zones" "available" {}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

resource "aws_eip" "acctest" {
  tags {
    foo  = "bar"
    Name = "${var.name}"
  }
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "arn:aws:ec2:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:eip-allocation/${aws_eip.acctest.id}"
}
`

var testAccShieldProtectionGlobalAcceleratorConfig = `
provider "aws" {
  region = "us-west-2"
  alias  = "globalaccelerator"
}

variable "name" {
  default = "%s"
}

resource "aws_shield_protection" "acctest" {
  name         = "${var.name}"
  resource_arn = "${aws_globalaccelerator_accelerator.acctest.id}"
}

resource "aws_globalaccelerator_accelerator" "acctest" {
  provider        = "aws.globalaccelerator"
  name            = "${var.name}"
  ip_address_type = "IPV4"
  enabled         = true
}
`
<|endoftext|>


<commit_before>package molecule

import (
	"fmt"
	"math"

	bits "github.com/willf/bitset"

	cmn "github.com/RxnWeaver/rxnweaver/common"
)

// Ring represents a simple cycle in a molecule.
//
// A ring holds information of the atoms and the bonds it comprises.
// It also knows its neighbouring rings.
//
// Rings are supposed to be immutable: once completed, their
// composition should never change.
//
// The atom IDs held by rings are their input IDs, to match those held
// by bonds.  That makes using atoms and bonds together easier, when
// doing ring detection, etc.
type Ring struct {
	mol  *Molecule // Containing molecule of this ring.
	id   uint8     // A unique identifier for this ring.
	rsId uint8     // ID of the ring system to which this ring belongs.

	atoms []uint16 // List of atoms participating in this ring.
	bonds []uint16 // List of bonds participating in this ring.
	nbrs  []uint8  // List of rings neighbouring this ring.

	atomBitSet *bits.BitSet // For faster comparison.
	bondBitSet *bits.BitSet // For faster comparison.

	isAro    bool // Is this ring aromatic?
	isHetAro bool // Is this an aromatic ring with at least one hetero atom?

	isComplete bool // Has this ring been finalised?
}

// newRing creates and initialises a new ring.
func newRing(mol *Molecule, id uint8) {
	r := new(Ring)
	r.mol = mol
	r.id = id

	r.atoms = make([]uint16, 0, cmn.ListSizeSmall)
	r.bonds = make([]uint16, 0, cmn.ListSizeSmall)
	r.nbrs = make([]uint8, 0, cmn.ListSizeSmall)

	r.atomBitSet = bits.New(cmn.ListSizeSmall)
	r.bondBitSet = bits.New(cmn.ListSizeSmall)
}

// size answers the size of this ring.  It is equivalently the number
// of atoms or the number of bonds participating in this ring.
func (r *Ring) size() int {
	return len(r.atoms)
}

// hasAtom answers if this ring includes the given atom.
func (r *Ring) hasAtom(aid uint16) bool {
	return r.atomBitSet.Test(uint(aid))
}

// atomIndex answers the index of the given atom in this ring, if it
// is found.  Answers `-1` otherwise.
//
// Note that the answer may or may not be idempotent, depending on the
// normalisation status of the ring.  Should the ring be normalised
// between two invocations of this method, the answers could vary.
func (r *Ring) atomIndex(aid uint16) int {
	if !r.hasAtom(aid) {
		return -1
	}

	for i, id := range r.atoms {
		if id == aid {
			return i
		}
	}

	panic("Should never be here!")
}

// hasBond answers if this ring includes the given bond.
func (r *Ring) hasBond(bid uint16) bool {
	return r.bondBitSet.Test(uint(bid))
}

// addAtom adds the given atom to this ring.
//
// This method errors if the ring is already completed.
//
// It checks to see that a bond exists between the most-recently-added
// atom, if one such exists, and the given atom.  Answers a non-nil
// error otherwise.
//
// This method is idempotent: the given atom is ignored if it is
// already a member of this ring.
func (r *Ring) addAtom(aid uint16) error {
	if r.isComplete {
		return fmt.Errorf("Ring already complete.  ID : %d.", r.id)
	}

	if r.hasAtom(aid) {
		return nil
	}

	size := len(r.atoms)
	if size == 0 {
		r.atoms = append(r.atoms, aid)
		return nil
	}

	prev := r.atoms[size-1]
	b := r.mol.bondBetween(prev, aid)
	if b == nil {
		return fmt.Errorf("No bond exists between atom %d and atom %d.", prev, aid)
	}

	r.bonds = append(r.bonds, b.id)
	r.atoms = append(r.atoms, aid)
	return nil
}

// complete closes the link between the last atom in the ring and the
// first.  This operation effectively freezes the ring.
//
// This method is idempotent.
func (r *Ring) complete() error {
	if r.isComplete {
		return nil
	}

	size := len(r.atoms)
	if size < 3 {
		return fmt.Errorf("A ring must have at least 3 atoms.  This ring has only %d.", size)
	}

	aid1 := r.atoms[0]
	aid2 := r.atoms[size-1]
	b := r.mol.bondBetween(aid1, aid2)
	if b == nil {
		return fmt.Errorf("No bond between first atom %d and last atom %d.", aid1, aid2)
	}

	r.bonds = append(r.bonds, b.id)

	for _, aid := range r.atoms {
		r.atomBitSet.Set(uint(aid))
	}
	for _, bid := range r.bonds {
		r.bondBitSet.Set(uint(bid))
	}

	r.isComplete = true
	return nil
}

// isAromatic answers if this ring is aromatic.
//
// The actual aromaticity determination happens when
// `determineAromaticity` is called.  This method merely answers the
// set flag.
func (r *Ring) isAromatic() bool {
	return r.isAro
}

// isHeteroAromatic answers if this ring is aromatic with at least one
// hetero atom.
//
// The actual aromaticity determination happens when
// `determineAromaticity` is called.  This method merely answers the
// set flag.
func (r *Ring) isHeteroAromatic() bool {
	return r.isHetAro
}

// normalise transforms the ring into a `standard' representation, in
// which the ring logically begins with that atom which has the lowest
// normalised ID.
func (r *Ring) normalise() error {
	l := len(r.atoms)
	if l == 0 {
		return fmt.Errorf("Cannot normalise an empty ring!")
	}

	nids := make([]uint16, l, l)

	mol := r.mol
	for i, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		nids[i] = a.nId
	}

	min := uint16(math.MaxUint16)
	idx := -1
	for i, nid := range nids {
		if nid < min {
			idx = i
			min = nid
		}
	}

	// Rotate the ring so that the atom at `idx` becomes the first.
	r.atoms = append(r.atoms[idx:], r.atoms[:idx]...)
	return nil
}

// piElectronCount answers the total number of pi-electrons in this
// ring.
func (r *Ring) piElectronCount() (int, bool) {
	n := 0
	mol := r.mol
	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		if c, ok := a.piElectronCount(); ok {
			n += c
		} else {
			return 0, false
		}
	}
	return n, true
}

// determineAromaticity examines this ring to see if it is aromatic in
// nature.
//
// TODO(js): May have to take exceptions into account, as we make
// progress.
func (r *Ring) determineAromaticity() {
	n, ok := r.piElectronCount()
	if !ok { // Some condition preventing this ring from becoming aromatic.
		return
	}

	mol := r.mol

	// First, we apply Hückel's rule.
	if (n-2)%4 != 0 {
		// TODO(js): Take exceptions into account.
		return
	}

	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		if a.atNum == 6 {
			if a.unsaturation == cmn.UnsaturationNone {
				return // There should not be any sp3 C atoms.
			}
		}
	}

	// TODO(js): Take exceptions into account.

	// If we have come this far, this is an aromatic ring.
	r.isAro = true

	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		a.isInAroRing = true
		if a.atNum != 6 {
			r.isHetAro = true
		}
	}
	for _, bid := range r.bonds {
		b := mol.bondWithId(bid)
		b.isAro = true
	}
}
<commit_msg>Add a few utility methods to `Ring`<commit_after>package molecule

import (
	"fmt"
	"math"

	bits "github.com/willf/bitset"

	cmn "github.com/RxnWeaver/rxnweaver/common"
)

// Ring represents a simple cycle in a molecule.
//
// A ring holds information of the atoms and the bonds it comprises.
// It also knows its neighbouring rings.
//
// Rings are supposed to be immutable: once completed, their
// composition should never change.
//
// The atom IDs held by rings are their input IDs, to match those held
// by bonds.  That makes using atoms and bonds together easier, when
// doing ring detection, etc.
type Ring struct {
	mol  *Molecule // Containing molecule of this ring.
	id   uint8     // A unique identifier for this ring.
	rsId uint8     // ID of the ring system to which this ring belongs.

	atoms []uint16 // List of atoms participating in this ring.
	bonds []uint16 // List of bonds participating in this ring.
	nbrs  []uint8  // List of rings neighbouring this ring.

	atomBitSet *bits.BitSet // For faster comparison.
	bondBitSet *bits.BitSet // For faster comparison.

	isAro    bool // Is this ring aromatic?
	isHetAro bool // Is this an aromatic ring with at least one hetero atom?

	isComplete bool // Has this ring been finalised?
}

// newRing creates and initialises a new ring.
func newRing(mol *Molecule, id uint8) {
	r := new(Ring)
	r.mol = mol
	r.id = id

	r.atoms = make([]uint16, 0, cmn.ListSizeSmall)
	r.bonds = make([]uint16, 0, cmn.ListSizeSmall)
	r.nbrs = make([]uint8, 0, cmn.ListSizeSmall)

	r.atomBitSet = bits.New(cmn.ListSizeSmall)
	r.bondBitSet = bits.New(cmn.ListSizeSmall)
}

// size answers the size of this ring.  It is equivalently the number
// of atoms or the number of bonds participating in this ring.
func (r *Ring) size() int {
	return len(r.atoms)
}

// hasAtom answers if this ring includes the given atom.
func (r *Ring) hasAtom(aid uint16) bool {
	return r.atomBitSet.Test(uint(aid))
}

// atomIndex answers the index of the given atom in this ring, if it
// is found.  Answers `-1` otherwise.
//
// Note that the answer may or may not be idempotent, depending on the
// normalisation status of the ring.  Should the ring be normalised
// between two invocations of this method, the answers could vary.
func (r *Ring) atomIndex(aid uint16) int {
	if !r.hasAtom(aid) {
		return -1
	}

	for i, id := range r.atoms {
		if id == aid {
			return i
		}
	}

	panic("Should never be here!")
}

// hasBond answers if this ring includes the given bond.
func (r *Ring) hasBond(bid uint16) bool {
	return r.bondBitSet.Test(uint(bid))
}

// addAtom adds the given atom to this ring.
//
// This method errors if the ring is already completed.
//
// It checks to see that a bond exists between the most-recently-added
// atom, if one such exists, and the given atom.  Answers a non-nil
// error otherwise.
//
// This method is idempotent: the given atom is ignored if it is
// already a member of this ring.
func (r *Ring) addAtom(aid uint16) error {
	if r.isComplete {
		return fmt.Errorf("Ring already complete.  ID : %d.", r.id)
	}

	if r.hasAtom(aid) {
		return nil
	}

	size := len(r.atoms)
	if size == 0 {
		r.atoms = append(r.atoms, aid)
		return nil
	}

	prev := r.atoms[size-1]
	b := r.mol.bondBetween(prev, aid)
	if b == nil {
		return fmt.Errorf("No bond exists between atom %d and atom %d.", prev, aid)
	}

	r.bonds = append(r.bonds, b.id)
	r.atoms = append(r.atoms, aid)
	return nil
}

// complete closes the link between the last atom in the ring and the
// first.  This operation effectively freezes the ring.
//
// This method is idempotent.
func (r *Ring) complete() error {
	if r.isComplete {
		return nil
	}

	size := len(r.atoms)
	if size < 3 {
		return fmt.Errorf("A ring must have at least 3 atoms.  This ring has only %d.", size)
	}

	aid1 := r.atoms[0]
	aid2 := r.atoms[size-1]
	b := r.mol.bondBetween(aid1, aid2)
	if b == nil {
		return fmt.Errorf("No bond between first atom %d and last atom %d.", aid1, aid2)
	}

	r.bonds = append(r.bonds, b.id)

	for _, aid := range r.atoms {
		r.atomBitSet.Set(uint(aid))
	}
	for _, bid := range r.bonds {
		r.bondBitSet.Set(uint(bid))
	}

	r.isComplete = true
	return nil
}

// isAromatic answers if this ring is aromatic.
//
// The actual aromaticity determination happens when
// `determineAromaticity` is called.  This method merely answers the
// set flag.
func (r *Ring) isAromatic() bool {
	return r.isAro
}

// isHeteroAromatic answers if this ring is aromatic with at least one
// hetero atom.
//
// The actual aromaticity determination happens when
// `determineAromaticity` is called.  This method merely answers the
// set flag.
func (r *Ring) isHeteroAromatic() bool {
	return r.isHetAro
}

// normalise transforms the ring into a `standard' representation, in
// which the ring logically begins with that atom which has the lowest
// normalised ID.
func (r *Ring) normalise() error {
	l := len(r.atoms)
	if l == 0 {
		return fmt.Errorf("Cannot normalise an empty ring!")
	}

	nids := make([]uint16, l, l)

	mol := r.mol
	for i, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		nids[i] = a.nId
	}

	min := uint16(math.MaxUint16)
	idx := -1
	for i, nid := range nids {
		if nid < min {
			idx = i
			min = nid
		}
	}

	// Rotate the ring so that the atom at `idx` becomes the first.
	r.atoms = append(r.atoms[idx:], r.atoms[:idx]...)
	return nil
}

// piElectronCount answers the total number of pi-electrons in this
// ring.
func (r *Ring) piElectronCount() (int, bool) {
	n := 0
	mol := r.mol
	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		if c, ok := a.piElectronCount(); ok {
			n += c
		} else {
			return 0, false
		}
	}
	return n, true
}

// determineAromaticity examines this ring to see if it is aromatic in
// nature.
//
// TODO(js): May have to take exceptions into account, as we make
// progress.
func (r *Ring) determineAromaticity() {
	n, ok := r.piElectronCount()
	if !ok { // Some condition preventing this ring from becoming aromatic.
		return
	}

	mol := r.mol

	// First, we apply Hückel's rule.
	if (n-2)%4 != 0 {
		// TODO(js): Take exceptions into account.
		return
	}

	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		if a.atNum == 6 {
			if a.unsaturation == cmn.UnsaturationNone {
				return // There should not be any sp3 C atoms.
			}
		}
	}

	// TODO(js): Take exceptions into account.

	// If we have come this far, this is an aromatic ring.
	r.isAro = true

	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		a.isInAroRing = true
		if a.atNum != 6 {
			r.isHetAro = true
		}
	}
	for _, bid := range r.bonds {
		b := mol.bondWithId(bid)
		b.isAro = true
	}
}

// commonAtoms answers a list of the atoms that participate in both
// this ring and the given ring.  The representation is a bitset.
func (r *Ring) commonAtoms(other *Ring) *bits.BitSet {
	return r.atomBitSet.Intersection(other.atomBitSet)
}

// commonBonds answers a list of the bonds that participate in both
// this ring and the given ring.  The representation is a bitset.
func (r *Ring) commonBonds(other *Ring) *bits.BitSet {
	return r.bondBitSet.Intersection(other.bondBitSet)
}

// distanceBetweenAtoms answers the shorter distance in the ring,
// between the two given atoms.
func (r *Ring) distanceBetweenAtoms(aid1, aid2 uint16) (int, error) {
	if !r.hasAtom(aid1) {
		return 0, fmt.Errorf("Atom %d is not a member of this ring.", aid1)
	}
	if !r.hasAtom(aid2) {
		return 0, fmt.Errorf("Atom %d is not a member of this ring.", aid2)
	}

	i1, i2 := -1, -1
	c := 0
	for i, aid := range r.atoms {
		switch {
		case aid == aid1:
			i1 = i
			c++
		case aid == aid2:
			i2 = i
			c++
		}
		if c == 2 {
			break
		}
	}

	d1 := i1 - i2
	if d1 < 0 {
		d1 = -d1
	}
	d2 := r.size() - d1
	if d1 < d2 {
		return d1, nil
	}
	return d2, nil
}

// isSemiAromaticOfSize6 answers if this ring satisfies the following
// constraints:
//
//     number of aromatic atoms + number of atoms in double bonds +
//         number of carbons with exocyclic double bonds to hetero atoms +
//         number of NH nitrogens
//     == 6
//
//     AND
//
//     number of carbons with exocyclic double bonds to hetero atoms
//     == number of NH nitrogens.
func (r *Ring) isSemiAromaticOfSize6() bool {
	if r.size() != 6 || r.isAro {
		return false
	}

	nAro := r.aromaticAtomCount()
	nDbly := r.doubleBondCount() * 2

	nNH := 0
	nExo := 0
	mol := r.mol
	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)

		switch a.atNum {
		case 6:
			for bid, ok := a.bonds.NextSet(0); ok; bid, ok = a.bonds.NextSet(bid + 1) {
				b := mol.bondWithId(uint16(bid))
				if !b.isCyclic() && b.bType == cmn.BondTypeDouble {
					nbrId := b.otherAtomIid(aiid)
					nbr := mol.atomWithIid(nbrId)
					if nbr.atNum != 6 { // Exocyclic hetero neighbour.
						nExo++
						break // Carbon can have only one such.
					}
				}
			}

		case 7:
			if a.hCount == 1 {
				nNH++
			}
		}
	}

	// All constituents are ready.
	sum := nAro + nDbly + nNH + nExo
	return sum == 6 && nNH == nExo
}

// aromaticAtomCount answers the number of atoms in this ring that are
// marked as aromatic.
//
// Note that it is possible for a non-aromatic ring to contain some
// aromatic atoms.
func (r *Ring) aromaticAtomCount() int {
	c := 0
	mol := r.mol
	for _, aiid := range r.atoms {
		a := mol.atomWithIid(aiid)
		if a.isInAroRing {
			c++
		}
	}
	return c
}

// doubleBondCount answers the number of double bonds in this ring.
func (r *Ring) doubleBondCount() int {
	c := 0
	mol := r.mol
	for _, bid := range r.bonds {
		b := mol.bondWithId(bid)
		if b.bType == cmn.BondTypeDouble {
			c++
		}
	}
	return c
}
<|endoftext|>