<commit_before>// +build linux freebsd solaris openbsd darwin

package compute

import (
	"context"
	"fmt"
	"strings"

	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/client"
)

// This approach was adopted from Weave's weaveproxy component. Proper credit goes to them.

var (
	waitProg         = "/.r/r"
	waitVolume       = "rancher-cni"
	waitVolumeTarget = "/.r"
)

func modifyForCNI(c *client.Client, container *container.Config, hostConfig *container.HostConfig) error {
	if container.Labels[cniWaitLabel] != "true" {
		return nil
	}
	if err := setWaitEntrypoint(c, container); err != nil {
		return err
	}
	return setWaitVolume(hostConfig, waitVolume, waitVolumeTarget, "ro")
}

func setWaitVolume(hostConfig *container.HostConfig, source, target, mode string) error {
	var binds []string
	for _, bind := range hostConfig.Binds {
		s := strings.Split(bind, ":")
		if len(s) >= 2 && s[1] == target {
			continue
		}
		binds = append(binds, bind)
	}
	hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s:%s:%s", source, target, mode))
	return nil
}

func setWaitEntrypoint(c *client.Client, container *container.Config) error {
	if len(container.Entrypoint) == 0 {
		image, _, err := c.ImageInspectWithRaw(context.Background(), container.Image)
		if err != nil {
			return err
		}

		if len(container.Cmd) == 0 {
			container.Cmd = image.Config.Cmd
		}

		if container.Entrypoint == nil {
			container.Entrypoint = image.Config.Entrypoint
		}
	}

	if len(container.Entrypoint) == 0 && len(container.Cmd) == 0 {
		// No command, just let docker complain about it on start
		return nil
	}

	if len(container.Entrypoint) == 0 || container.Entrypoint[0] != waitProg {
		container.Entrypoint = append(container.Entrypoint, waitProg)
	}

	return nil
}
<commit_msg>Fix wrong entrypoint insertion<commit_after>// +build linux freebsd solaris openbsd darwin

package compute

import (
	"context"
	"fmt"
	"strings"

	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/client"
)

// This approach was adopted from Weave's weaveproxy component. Proper credit goes to them.

var (
	waitProg         = "/.r/r"
	waitVolume       = "rancher-cni"
	waitVolumeTarget = "/.r"
)

func modifyForCNI(c *client.Client, container *container.Config, hostConfig *container.HostConfig) error {
	if container.Labels[cniWaitLabel] != "true" {
		return nil
	}
	if err := setWaitEntrypoint(c, container); err != nil {
		return err
	}
	return setWaitVolume(hostConfig, waitVolume, waitVolumeTarget, "ro")
}

func setWaitVolume(hostConfig *container.HostConfig, source, target, mode string) error {
	var binds []string
	for _, bind := range hostConfig.Binds {
		s := strings.Split(bind, ":")
		if len(s) >= 2 && s[1] == target {
			continue
		}
		binds = append(binds, bind)
	}
	hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s:%s:%s", source, target, mode))
	return nil
}

func setWaitEntrypoint(c *client.Client, container *container.Config) error {
	if len(container.Entrypoint) == 0 {
		image, _, err := c.ImageInspectWithRaw(context.Background(), container.Image)
		if err != nil {
			return err
		}

		if len(container.Cmd) == 0 {
			container.Cmd = image.Config.Cmd
		}

		if container.Entrypoint == nil {
			container.Entrypoint = image.Config.Entrypoint
		}
	}

	if len(container.Entrypoint) == 0 && len(container.Cmd) == 0 {
		// No command, just let docker complain about it on start
		return nil
	}

	if len(container.Entrypoint) == 0 || container.Entrypoint[0] != waitProg {
		container.Entrypoint = append([]string{waitProg}, container.Entrypoint...)
	}

	return nil
}
<|endoftext|>


<commit_before>package helper

import (
	. "fruit-service/core"
	"reflect"
	"strings"

	reflections "gopkg.in/oleiade/reflections.v1"
)

func CheckQueryCondition(dto *APIParam, checkStruct interface{}) (apiResult *APIResult) {
	var err error
	if len(dto.Fields) != 0 {
		var ok bool
		fields := strings.Split(dto.Fields, ",")
		for _, v := range fields {
			if ok, err = reflections.HasField(checkStruct, v); err != nil || ok == false {
				dto = nil
				apiResult = NewApiMessage(10011, "", v)
				return
			}
		}
	}
	if dto.MaxResultCount == 0 {
		dto.MaxResultCount = 10
	} else if dto.MaxResultCount > 10000 {
		dto.MaxResultCount = 10000
	}

	if len(dto.Sort) != 0 {
		sorts := strings.Split(dto.Sort, ",")
		for _, v := range sorts {
			if strings.HasPrefix(v, "-") {
				v = string(v[1:])
				dto.SortDesc += "," + v
			} else {
				dto.SortAsc += "," + v
			}

			if ok, err := reflections.HasField(checkStruct, v); err != nil || ok == false {
				dto = nil
				apiResult = NewApiMessage(10011, "", v)
				return
			}
		}
		if len(dto.SortDesc) != 0 {
			dto.SortDesc = dto.SortDesc[1:]
		}
		if len(dto.SortAsc) != 0 {
			dto.SortAsc = dto.SortAsc[1:]
		}
	}
	apiResult = nil
	return
}

func FilterFieldsMap(objArray interface{}, fields []string) []map[string]interface{} {
	slice, _ := takeArg(objArray, reflect.Slice)
	returnMaps := []map[string]interface{}{}
	for i := 0; i < slice.Len(); i++ {
		returnMap := make(map[string]interface{})
		for _, k := range fields {
			camelCase(&k)
			returnMap[k], _ = reflections.GetField(slice.Index(i).Interface(), k)
		}
		returnMaps = append(returnMaps, returnMap)
	}
	return returnMaps
}

func camelCase(input *string) {
	if len(*input) != 0 {
		*input = strings.ToLower((*input)[0:1]) + (*input)[1:]
	}
}

func takeArg(arg interface{}, kind reflect.Kind) (val reflect.Value, ok bool) {
	val = reflect.ValueOf(arg)
	if val.Kind() == kind {
		ok = true
	}
	return
}
<commit_msg>fix camelcase<commit_after>package helper

import (
	. "fruit-service/core"
	"reflect"
	"strings"

	reflections "gopkg.in/oleiade/reflections.v1"
)

func CheckQueryCondition(dto *APIParam, checkStruct interface{}) (apiResult *APIResult) {
	var err error
	if len(dto.Fields) != 0 {
		var ok bool
		fields := strings.Split(dto.Fields, ",")
		for _, v := range fields {
			if ok, err = reflections.HasField(checkStruct, v); err != nil || ok == false {
				dto = nil
				apiResult = NewApiMessage(10011, "", v)
				return
			}
		}
	}
	if dto.MaxResultCount == 0 {
		dto.MaxResultCount = 10
	} else if dto.MaxResultCount > 10000 {
		dto.MaxResultCount = 10000
	}

	if len(dto.Sort) != 0 {
		sorts := strings.Split(dto.Sort, ",")
		for _, v := range sorts {
			if strings.HasPrefix(v, "-") {
				v = string(v[1:])
				dto.SortDesc += "," + v
			} else {
				dto.SortAsc += "," + v
			}

			if ok, err := reflections.HasField(checkStruct, v); err != nil || ok == false {
				dto = nil
				apiResult = NewApiMessage(10011, "", v)
				return
			}
		}
		if len(dto.SortDesc) != 0 {
			dto.SortDesc = dto.SortDesc[1:]
		}
		if len(dto.SortAsc) != 0 {
			dto.SortAsc = dto.SortAsc[1:]
		}
	}
	apiResult = nil
	return
}

func FilterFieldsMap(objArray interface{}, fields []string) []map[string]interface{} {
	slice, _ := takeArg(objArray, reflect.Slice)
	returnMaps := []map[string]interface{}{}
	oldK := ""
	for i := 0; i < slice.Len(); i++ {
		returnMap := make(map[string]interface{})
		for _, k := range fields {
			oldK = k
			camelCase(&k)
			returnMap[k], _ = reflections.GetField(slice.Index(i).Interface(), oldK)
		}
		returnMaps = append(returnMaps, returnMap)
	}
	return returnMaps
}

func camelCase(input *string) {
	if len(*input) != 0 {
		*input = strings.ToLower((*input)[0:1]) + (*input)[1:]
	}
}

func takeArg(arg interface{}, kind reflect.Kind) (val reflect.Value, ok bool) {
	val = reflect.ValueOf(arg)
	if val.Kind() == kind {
		ok = true
	}
	return
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/codeartifact"
	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func init() {
	resource.AddTestSweepers("aws_codeartifact_domain", &resource.Sweeper{
		Name: "aws_codeartifact_domain",
		F:    testSweepCodeArtifactDomains,
	})
}

func testSweepCodeArtifactDomains(region string) error {
	client, err := sharedClientForRegion(region)
	if err != nil {
		return fmt.Errorf("error getting client: %s", err)
	}
	conn := client.(*AWSClient).codeartifactconn
	input := &codeartifact.ListDomainsInput{}
	var sweeperErrs *multierror.Error

	err = conn.ListDomainsPages(input, func(page *codeartifact.ListDomainsOutput, lastPage bool) bool {
		for _, domainPtr := range page.Domains {
			if domainPtr == nil {
				continue
			}

			domain := aws.StringValue(domainPtr.Name)
			input := &codeartifact.DeleteDomainInput{
				Domain: domainPtr.Name,
			}

			log.Printf("[INFO] Deleting CodeArtifact Domain: %s", domain)

			_, err := conn.DeleteDomain(input)

			if err != nil {
				sweeperErr := fmt.Errorf("error deleting CodeArtifact Domain (%s): %w", domain, err)
				log.Printf("[ERROR] %s", sweeperErr)
				sweeperErrs = multierror.Append(sweeperErrs, sweeperErr)
			}
		}

		return !lastPage
	})

	if testSweepSkipSweepError(err) {
		log.Printf("[WARN] Skipping CodeArtifact Domain sweep for %s: %s", region, err)
		return nil
	}

	if err != nil {
		return fmt.Errorf("error listing CodeArtifact Domains: %w", err)
	}

	return sweeperErrs.ErrorOrNil()
}

func TestAccAWSCodeArtifactDomain_basic(t *testing.T) {
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_codeartifact_domain.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSCodeArtifactDomainDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSCodeArtifactDomainBasicConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSCodeArtifactDomainExists(resourceName),
					testAccCheckResourceAttrRegionalARN(resourceName, "arn", "codeartifact", fmt.Sprintf("domain/%s", rName)),
					resource.TestCheckResourceAttr(resourceName, "domain", rName),
					resource.TestCheckResourceAttr(resourceName, "asset_size_bytes", "0"),
					resource.TestCheckResourceAttr(resourceName, "repository_count", "0"),
					resource.TestCheckResourceAttrSet(resourceName, "created_time"),
					resource.TestCheckResourceAttrPair(resourceName, "encryption_key", "aws_kms_key.test", "arn"),
					testAccCheckResourceAttrAccountID(resourceName, "owner"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSCodeArtifactDomain_disappears(t *testing.T) {
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_codeartifact_domain.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSCodeArtifactDomainDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSCodeArtifactDomainBasicConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSCodeArtifactDomainExists(resourceName),
					testAccCheckResourceDisappears(testAccProvider, resourceAwsCodeArtifactDomain(), resourceName),
				),
				ExpectNonEmptyPlan: true,
			},
		},
	})
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("no CodeArtifact domain set")
		}

		conn := testAccProvider.Meta().(*AWSClient).codeartifactconn

		domainOwner, domainName, err := decodeCodeArtifactDomainID(rs.Primary.ID)
		if err != nil {
			return err
		}

		_, err = conn.DescribeDomain(&codeartifact.DescribeDomainInput{
			Domain:      aws.String(domainName),
			DomainOwner: aws.String(domainOwner),
		})

		return err
	}
}

func testAccCheckAWSCodeArtifactDomainDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_codeartifact_domain" {
			continue
		}

		conn := testAccProvider.Meta().(*AWSClient).codeartifactconn

		domainOwner, domainName, err := decodeCodeArtifactDomainID(rs.Primary.ID)
		if err != nil {
			return err
		}

		resp, err := conn.DescribeDomain(&codeartifact.DescribeDomainInput{
			Domain:      aws.String(domainName),
			DomainOwner: aws.String(domainOwner),
		})

		if err == nil {
			if aws.StringValue(resp.Domain.Arn) == rs.Primary.ID {
				return fmt.Errorf("CodeArtifact Domain %s still exists", rs.Primary.ID)
			}
		}

		if isAWSErr(err, codeartifact.ErrCodeResourceNotFoundException, "") {
			return nil
		}

		return err
	}

	return nil
}

func testAccAWSCodeArtifactDomainBasicConfig(rName string) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "test" {
  description = %[1]q
  deletion_window_in_days = 7
}

resource "aws_codeartifact_domain" "test" {
  domain         = %[1]q
  encryption_key = aws_kms_key.test.arn
}
`, rName)
}
<commit_msg>test lint<commit_after>package aws

import (
	"fmt"
	"log"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/codeartifact"
	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func init() {
	resource.AddTestSweepers("aws_codeartifact_domain", &resource.Sweeper{
		Name: "aws_codeartifact_domain",
		F:    testSweepCodeArtifactDomains,
	})
}

func testSweepCodeArtifactDomains(region string) error {
	client, err := sharedClientForRegion(region)
	if err != nil {
		return fmt.Errorf("error getting client: %s", err)
	}
	conn := client.(*AWSClient).codeartifactconn
	input := &codeartifact.ListDomainsInput{}
	var sweeperErrs *multierror.Error

	err = conn.ListDomainsPages(input, func(page *codeartifact.ListDomainsOutput, lastPage bool) bool {
		for _, domainPtr := range page.Domains {
			if domainPtr == nil {
				continue
			}

			domain := aws.StringValue(domainPtr.Name)
			input := &codeartifact.DeleteDomainInput{
				Domain: domainPtr.Name,
			}

			log.Printf("[INFO] Deleting CodeArtifact Domain: %s", domain)

			_, err := conn.DeleteDomain(input)

			if err != nil {
				sweeperErr := fmt.Errorf("error deleting CodeArtifact Domain (%s): %w", domain, err)
				log.Printf("[ERROR] %s", sweeperErr)
				sweeperErrs = multierror.Append(sweeperErrs, sweeperErr)
			}
		}

		return !lastPage
	})

	if testSweepSkipSweepError(err) {
		log.Printf("[WARN] Skipping CodeArtifact Domain sweep for %s: %s", region, err)
		return nil
	}

	if err != nil {
		return fmt.Errorf("error listing CodeArtifact Domains: %w", err)
	}

	return sweeperErrs.ErrorOrNil()
}

func TestAccAWSCodeArtifactDomain_basic(t *testing.T) {
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_codeartifact_domain.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSCodeArtifactDomainDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSCodeArtifactDomainBasicConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSCodeArtifactDomainExists(resourceName),
					testAccCheckResourceAttrRegionalARN(resourceName, "arn", "codeartifact", fmt.Sprintf("domain/%s", rName)),
					resource.TestCheckResourceAttr(resourceName, "domain", rName),
					resource.TestCheckResourceAttr(resourceName, "asset_size_bytes", "0"),
					resource.TestCheckResourceAttr(resourceName, "repository_count", "0"),
					resource.TestCheckResourceAttrSet(resourceName, "created_time"),
					resource.TestCheckResourceAttrPair(resourceName, "encryption_key", "aws_kms_key.test", "arn"),
					testAccCheckResourceAttrAccountID(resourceName, "owner"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAWSCodeArtifactDomain_disappears(t *testing.T) {
	rName := acctest.RandomWithPrefix("tf-acc-test")
	resourceName := "aws_codeartifact_domain.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSCodeArtifactDomainDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSCodeArtifactDomainBasicConfig(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSCodeArtifactDomainExists(resourceName),
					testAccCheckResourceDisappears(testAccProvider, resourceAwsCodeArtifactDomain(), resourceName),
				),
				ExpectNonEmptyPlan: true,
			},
		},
	})
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("no CodeArtifact domain set")
		}

		conn := testAccProvider.Meta().(*AWSClient).codeartifactconn

		domainOwner, domainName, err := decodeCodeArtifactDomainID(rs.Primary.ID)
		if err != nil {
			return err
		}

		_, err = conn.DescribeDomain(&codeartifact.DescribeDomainInput{
			Domain:      aws.String(domainName),
			DomainOwner: aws.String(domainOwner),
		})

		return err
	}
}

func testAccCheckAWSCodeArtifactDomainDestroy(s *terraform.State) error {
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_codeartifact_domain" {
			continue
		}

		conn := testAccProvider.Meta().(*AWSClient).codeartifactconn

		domainOwner, domainName, err := decodeCodeArtifactDomainID(rs.Primary.ID)
		if err != nil {
			return err
		}

		resp, err := conn.DescribeDomain(&codeartifact.DescribeDomainInput{
			Domain:      aws.String(domainName),
			DomainOwner: aws.String(domainOwner),
		})

		if err == nil {
			if aws.StringValue(resp.Domain.Arn) == rs.Primary.ID {
				return fmt.Errorf("CodeArtifact Domain %s still exists", rs.Primary.ID)
			}
		}

		if isAWSErr(err, codeartifact.ErrCodeResourceNotFoundException, "") {
			return nil
		}

		return err
	}

	return nil
}

func testAccAWSCodeArtifactDomainBasicConfig(rName string) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "test" {
  description             = %[1]q
  deletion_window_in_days = 7
}

resource "aws_codeartifact_domain" "test" {
  domain         = %[1]q
  encryption_key = aws_kms_key.test.arn
}
`, rName)
}
<|endoftext|>


<commit_before>package azurerm

import (
	"fmt"
	"net/http"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func TestAccAzureRMContainerGroup_basicLinux(t *testing.T) {
	ri := acctest.RandInt()

	config := testAccAzureRMContainerGroupBasicLinux(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMContainerGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMContainerGroupExists("azurerm_container_group.test"),
				),
			},
		},
	})
}

func TestAccAzureRMContainerGroup_basicWindows(t *testing.T) {
	ri := acctest.RandInt()

	config := testAccAzureRMContainerGroupBasicWindows(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMContainerGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMContainerGroupExists("azurerm_container_group.test"),
				),
			},
		},
	})
}

func testAccAzureRMContainerGroupBasicLinux(ri int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
  name     = "acctestRG-%d"
  location = "%s"
}

resource "azurerm_container_group" "test" {

	name = "acctestcontainergroup-%d"
	location = "${azurerm_resource_group.test.location}"
	resource_group_name = "${azurerm_resource_group.test.name}"
	ip_address_type="public"
	os_type = "linux"

	container {
        name = "hw"
        image = "microsoft/aci-helloworld:latest"
        cpu ="0.5"
        memory =  "1.5"
        port = "80"
    }
    container {
        name = "sidecar"
        image = "microsoft/aci-tutorial-sidecar"
        cpu="0.5"
        memory="1.5"
    }

	tags {
	  environment = "testing"
	}
  }
`, ri, location, ri)
}

func testAccAzureRMContainerGroupBasicWindows(ri int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
  name     = "acctestRG-%d"
  location = "%s"
}

resource "azurerm_container_group" "test" {

	name = "acctestcontainergroup-%d"
	location = "${azurerm_resource_group.test.location}"
	resource_group_name = "${azurerm_resource_group.test.name}"
	ip_address_type="public"
	os_type = "windows"

	container {
	  name = "winapp"
	  image = "winappimage:latest"
	  cpu ="2.0"
	  memory = "3.5"
	  port = "80"
	}

	tags {
	  environment = "testing"
	}
  }
`, ri, location, ri)
}

func testCheckAzureRMContainerGroupExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		// Ensure we have enough information in state to look up in API
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		name := rs.Primary.Attributes["name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for Container Registry: %s", name)
		}

		conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient

		resp, err := conn.Get(resourceGroup, name)
		if err != nil {
			if utils.ResponseWasNotFound(resp.Response) {
				return fmt.Errorf("Bad: Container Group %q (resource group: %q) does not exist", name, resourceGroup)
			}
			return fmt.Errorf("Bad: Get on containerGroupsClient: %+v", err)
		}

		return nil
	}
}

func testCheckAzureRMContainerGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "azurerm_container_group" {
			continue
		}

		name := rs.Primary.Attributes["name"]
		resourceGroup := rs.Primary.Attributes["resource_group_name"]

		resp, err := conn.Get(resourceGroup, name)

		if err != nil {
			if resp.StatusCode != http.StatusNotFound {
				return fmt.Errorf("Container Group still exists:\n%#v", resp)
			}

			return nil
		}

	}

	return nil
}
<commit_msg>Adding an acceptance test covering updating containers<commit_after>package azurerm

import (
	"fmt"
	"net/http"
	"testing"

	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func TestAccAzureRMContainerGroup_basicLinux(t *testing.T) {
	ri := acctest.RandInt()

	config := testAccAzureRMContainerGroupBasicLinux(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMContainerGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMContainerGroupExists("azurerm_container_group.test"),
				),
			},
		},
	})
}
func TestAccAzureRMContainerGroup_basicLinuxUpdate(t *testing.T) {
	resourceName := "azurerm_container_group.test"
	ri := acctest.RandInt()

	config := testAccAzureRMContainerGroupBasicLinux(ri, testLocation())
	updatedConfig := testAccAzureRMContainerGroupBasicLinuxUpdated(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMContainerGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMContainerGroupExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "container.#", "1"),
				),
			},
			{
				Config: updatedConfig,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMContainerGroupExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "container.#", "2"),
				),
			},
		},
	})
}

func TestAccAzureRMContainerGroup_basicWindows(t *testing.T) {
	ri := acctest.RandInt()

	config := testAccAzureRMContainerGroupBasicWindows(ri, testLocation())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testCheckAzureRMContainerGroupDestroy,
		Steps: []resource.TestStep{
			{
				Config: config,
				Check: resource.ComposeTestCheckFunc(
					testCheckAzureRMContainerGroupExists("azurerm_container_group.test"),
				),
			},
		},
	})
}

func testAccAzureRMContainerGroupBasicLinux(ri int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
  name     = "acctestRG-%d"
  location = "%s"
}

resource "azurerm_container_group" "test" {
  name                = "acctestcontainergroup-%d"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  ip_address_type     = "public"
  os_type             = "linux"

  container {
    name   = "hw"
    image  = "microsoft/aci-helloworld:latest"
    cpu    = "0.5"
    memory = "0.5"
    port   = "80"
  }

  tags {
    environment = "testing"
  }
}
`, ri, location, ri)
}

func testAccAzureRMContainerGroupBasicLinuxUpdated(ri int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
  name     = "acctestRG-%d"
  location = "%s"
}

resource "azurerm_container_group" "test" {
  name                = "acctestcontainergroup-%d"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  ip_address_type     = "public"
  os_type             = "linux"

  container {
    name   = "hw"
    image  = "microsoft/aci-helloworld:latest"
    cpu    = "0.5"
    memory = "0.5"
    port   = "80"
  }

  container {
    name   = "sidecar"
    image  = "microsoft/aci-tutorial-sidecar"
    cpu    = "0.5"
    memory = "0.5"
  }

  tags {
    environment = "testing"
  }
}
`, ri, location, ri)
}

func testAccAzureRMContainerGroupBasicWindows(ri int, location string) string {
	return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
  name     = "acctestRG-%d"
  location = "%s"
}

resource "azurerm_container_group" "test" {
  name                = "acctestcontainergroup-%d"
  location            = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  ip_address_type     = "public"
  os_type             = "windows"

  container {
    name   = "winapp"
    image  = "winappimage:latest"
    cpu    = "2.0"
    memory = "3.5"
    port   = "80"
  }

  tags {
    environment = "testing"
  }
}
`, ri, location, ri)
}

func testCheckAzureRMContainerGroupExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		// Ensure we have enough information in state to look up in API
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		name := rs.Primary.Attributes["name"]
		resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
		if !hasResourceGroup {
			return fmt.Errorf("Bad: no resource group found in state for Container Registry: %s", name)
		}

		conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient

		resp, err := conn.Get(resourceGroup, name)
		if err != nil {
			if utils.ResponseWasNotFound(resp.Response) {
				return fmt.Errorf("Bad: Container Group %q (resource group: %q) does not exist", name, resourceGroup)
			}
			return fmt.Errorf("Bad: Get on containerGroupsClient: %+v", err)
		}

		return nil
	}
}

func testCheckAzureRMContainerGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "azurerm_container_group" {
			continue
		}

		name := rs.Primary.Attributes["name"]
		resourceGroup := rs.Primary.Attributes["resource_group_name"]

		resp, err := conn.Get(resourceGroup, name)

		if err != nil {
			if resp.StatusCode != http.StatusNotFound {
				return fmt.Errorf("Container Group still exists:\n%#v", resp)
			}

			return nil
		}

	}

	return nil
}
<|endoftext|>


<commit_before>package graphqltest

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/Khan/genqlient/graphql"

	"github.com/oinume/lekcije/backend/context_data"
	interfacehttp "github.com/oinume/lekcije/backend/interface/http"
	"github.com/oinume/lekcije/backend/internal/assertion"
	"github.com/oinume/lekcije/backend/internal/modeltest"
	"github.com/oinume/lekcije/backend/internal/mysqltest"
	"github.com/oinume/lekcije/backend/model"
	"github.com/oinume/lekcije/backend/model2"
	"github.com/oinume/lekcije/backend/usecase"
)

var _ = `# @genqlient
mutation UpdateViewer($input: UpdateViewerInput!) {
  updateViewer(input: $input) {
    id
    email
  }
}
`

func TestUpdateViewer(t *testing.T) {
	helper := model.NewTestHelper()
	db := helper.DB(t)
	repos := mysqltest.NewRepositories(db.DB())
	//var log bytes.Buffer
	//appLogger := logger.NewAppLogger(&log, logger.NewLevel("info"))

	type testCase struct {
		apiToken   string
		input      UpdateViewerInput
		wantResult UpdateViewerUpdateViewerUser
		//wantResponse   *api_v1.GetMeResponse
		//wantStatusCode int
	}
	tests := map[string]struct {
		setup func(ctx context.Context) *testCase
	}{
		"ok": {
			setup: func(ctx context.Context) *testCase {
				user := modeltest.NewUser()
				repos.CreateUsers(ctx, t, user)
				userAPIToken := modeltest.NewUserAPIToken(func(uat *model2.UserAPIToken) {
					uat.UserID = user.ID
				})
				repos.CreateUserAPITokens(ctx, t, userAPIToken)
				newEmail := fmt.Sprintf("updated-%d@example.com", user.ID)
				return &testCase{
					apiToken: userAPIToken.Token,
					input: UpdateViewerInput{
						Email: newEmail,
					},
					wantResult: UpdateViewerUpdateViewerUser{
						Id:    fmt.Sprint(user.ID),
						Email: newEmail,
					},
				}
			},
		},
	}

	for name, test := range tests {
		t.Run(name, func(t *testing.T) {
			ctx := context.Background()
			tc := test.setup(ctx)
			userUsecase := usecase.NewUser(repos.DB(), repos.User(), repos.UserGoogle())
			graphqlServer := newGraphQLServer(repos, userUsecase)

			//server := httptest.NewServer(interfacehttp.WithIDToken(interfacehttp.WithSessionID(graphqlServer.ServeHTTP,
			// config.ServiceEnvTest)))
			server := httptest.NewServer(setAuthorizationContext(graphqlServer))
			t.Cleanup(func() { server.Close() })

			httpClient := server.Client()
			transport := httpClient.Transport
			httpClient.Transport = &authTransport{
				parent: transport,
				token:  tc.apiToken,
			}
			graphqlClient := graphql.NewClient(server.URL, httpClient)

			resp, err := UpdateViewer(ctx, graphqlClient, tc.input)
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			//if err != nil {
			//	if c.wantErrorCode == "" {
			//		t.Fatalf("unexpected error: %v", err)
			//	} else {
			//		if !strings.Contains(err.Error(), c.wantErrorCode.ErrorCode()) {
			//			t.Fatalf("err must contain code: wantErrorCode=%v, err=%v", c.wantErrorCode, err)
			//		}
			//		return // OK
			//	}
			//}
			//
			//if c.wantErrorCode != "" {
			//	t.Fatalf("wantErrorCode is not empty but no error: wantErrorCode=%v", c.wantErrorCode)
			//}
			assertion.AssertEqual(t, tc.wantResult, resp.GetUpdateViewer(), "")
		})
	}
}

func setAuthorizationContext(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		auth, err := interfacehttp.ParseAuthorizationHeader(r.Header.Get("authorization"))
		if err != nil {
			h.ServeHTTP(w, r)
			return
		}
		r = r.WithContext(context_data.SetAPIToken(r.Context(), strings.TrimSpace(auth)))
		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}
<commit_msg>Add error test cases<commit_after>package graphqltest

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/Khan/genqlient/graphql"
	"github.com/morikuni/failure"

	"github.com/oinume/lekcije/backend/context_data"
	"github.com/oinume/lekcije/backend/errors"
	interfacehttp "github.com/oinume/lekcije/backend/interface/http"
	"github.com/oinume/lekcije/backend/internal/assertion"
	"github.com/oinume/lekcije/backend/internal/modeltest"
	"github.com/oinume/lekcije/backend/internal/mysqltest"
	"github.com/oinume/lekcije/backend/model"
	"github.com/oinume/lekcije/backend/model2"
	"github.com/oinume/lekcije/backend/usecase"
)

var _ = `# @genqlient
mutation UpdateViewer($input: UpdateViewerInput!) {
  updateViewer(input: $input) {
    id
    email
  }
}
`

func TestUpdateViewer(t *testing.T) {
	helper := model.NewTestHelper()
	db := helper.DB(t)
	repos := mysqltest.NewRepositories(db.DB())

	type testCase struct {
		apiToken      string
		input         UpdateViewerInput
		wantResult    UpdateViewerUpdateViewerUser
		wantErrorCode failure.StringCode
		//wantResponse   *api_v1.GetMeResponse
		//wantStatusCode int
	}
	tests := map[string]struct {
		setup func(ctx context.Context) *testCase
	}{
		"ok": {
			setup: func(ctx context.Context) *testCase {
				user := modeltest.NewUser()
				repos.CreateUsers(ctx, t, user)
				userAPIToken := modeltest.NewUserAPIToken(func(uat *model2.UserAPIToken) {
					uat.UserID = user.ID
				})
				repos.CreateUserAPITokens(ctx, t, userAPIToken)
				newEmail := fmt.Sprintf("updated-%d@example.com", user.ID)
				return &testCase{
					apiToken: userAPIToken.Token,
					input: UpdateViewerInput{
						Email: newEmail,
					},
					wantResult: UpdateViewerUpdateViewerUser{
						Id:    fmt.Sprint(user.ID),
						Email: newEmail,
					},
					wantErrorCode: "",
				}
			},
		},
		"invalid_email_format": {
			setup: func(ctx context.Context) *testCase {
				user := modeltest.NewUser()
				repos.CreateUsers(ctx, t, user)
				userAPIToken := modeltest.NewUserAPIToken(func(uat *model2.UserAPIToken) {
					uat.UserID = user.ID
				})
				repos.CreateUserAPITokens(ctx, t, userAPIToken)
				newEmail := "invalid"
				return &testCase{
					apiToken: userAPIToken.Token,
					input: UpdateViewerInput{
						Email: newEmail,
					},
					wantResult: UpdateViewerUpdateViewerUser{
						Id:    fmt.Sprint(user.ID),
						Email: newEmail,
					},
					wantErrorCode: errors.InvalidArgument,
				}
			},
		},
		"duplicate_email": {
			setup: func(ctx context.Context) *testCase {
				user := modeltest.NewUser()
				repos.CreateUsers(ctx, t, user)
				userAPIToken := modeltest.NewUserAPIToken(func(uat *model2.UserAPIToken) {
					uat.UserID = user.ID
				})
				repos.CreateUserAPITokens(ctx, t, userAPIToken)
				newEmail := user.Email
				return &testCase{
					apiToken: userAPIToken.Token,
					input: UpdateViewerInput{
						Email: newEmail,
					},
					wantResult: UpdateViewerUpdateViewerUser{
						Id:    fmt.Sprint(user.ID),
						Email: newEmail,
					},
					wantErrorCode: errors.InvalidArgument,
				}
			},
		},
	}

	for name, test := range tests {
		t.Run(name, func(t *testing.T) {
			ctx := context.Background()
			tc := test.setup(ctx)
			userUsecase := usecase.NewUser(repos.DB(), repos.User(), repos.UserGoogle())
			graphqlServer := newGraphQLServer(repos, userUsecase)
			server := httptest.NewServer(setAuthorizationContext(graphqlServer))
			t.Cleanup(func() { server.Close() })

			httpClient := server.Client()
			transport := httpClient.Transport
			httpClient.Transport = &authTransport{
				parent: transport,
				token:  tc.apiToken,
			}
			graphqlClient := graphql.NewClient(server.URL, httpClient)

			resp, err := UpdateViewer(ctx, graphqlClient, tc.input)
			if err != nil {
				if tc.wantErrorCode == "" {
					t.Fatalf("unexpected error: %v", err)
				} else {
					if !strings.Contains(err.Error(), tc.wantErrorCode.ErrorCode()) {
						t.Fatalf("err must contain code: wantErrorCode=%v, err=%v", tc.wantErrorCode, err)
					}
					return // OK
				}
			}

			if tc.wantErrorCode != "" {
				t.Fatalf("wantErrorCode is not empty but no error: wantErrorCode=%v", tc.wantErrorCode)
			}

			assertion.AssertEqual(t, tc.wantResult, resp.GetUpdateViewer(), "")
		})
	}
}

func setAuthorizationContext(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		auth, err := interfacehttp.ParseAuthorizationHeader(r.Header.Get("authorization"))
		if err != nil {
			h.ServeHTTP(w, r)
			return
		}
		r = r.WithContext(context_data.SetAPIToken(r.Context(), strings.TrimSpace(auth)))
		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}
<|endoftext|>


<commit_before>//
// Last.Backend LLC CONFIDENTIAL
// __________________
//
// [2014] - [2018] Last.Backend LLC
// All Rights Reserved.
//
// NOTICE:  All information contained herein is, and remains
// the property of Last.Backend LLC and its suppliers,
// if any.  The intellectual and technical concepts contained
// herein are proprietary to Last.Backend LLC
// and its suppliers and may be covered by Russian Federation and Foreign Patents,
// patents in process, and are protected by trade secret or copyright law.
// Dissemination of this information or reproduction of this material
// is strictly forbidden unless prior written permission is obtained
// from Last.Backend LLC.
//

package request

import (
	"encoding/json"
	"io"
	"io/ioutil"

	"github.com/lastbackend/lastbackend/pkg/distribution/errors"
	"github.com/lastbackend/lastbackend/pkg/util/validator"
)

type ServiceRequest struct{}

func (ServiceRequest) Manifest() *ServiceManifest {
	return new(ServiceManifest)
}

func (s *ServiceManifest) Validate() *errors.Err {
	switch true {
	case s.Meta.Name != nil && !validator.IsServiceName(*s.Meta.Name):
		return errors.New("service").BadParameter("name")
	case s.Meta.Description != nil && len(*s.Meta.Description) > DEFAULT_DESCRIPTION_LIMIT:
		return errors.New("service").BadParameter("description")
	}

	return nil
}

func (s *ServiceManifest) DecodeAndValidate(reader io.Reader) *errors.Err {

	if reader == nil {
		err := errors.New("data body can not be null")
		return errors.New("service").IncorrectJSON(err)
	}

	body, err := ioutil.ReadAll(reader)
	if err != nil {
		return errors.New("service").Unknown(err)
	}

	err = json.Unmarshal(body, s)
	if err != nil {
		return errors.New("service").IncorrectJSON(err)
	}

	if err := s.Validate(); err != nil {
		return err
	}

	return nil
}

func (ServiceRequest) RemoveOptions() *ServiceRemoveOptions {
	return new(ServiceRemoveOptions)
}

func (s *ServiceRemoveOptions) Validate() *errors.Err {
	return nil
}
<commit_msg>update validation request for service manifest<commit_after>//
// Last.Backend LLC CONFIDENTIAL
// __________________
//
// [2014] - [2018] Last.Backend LLC
// All Rights Reserved.
//
// NOTICE:  All information contained herein is, and remains
// the property of Last.Backend LLC and its suppliers,
// if any.  The intellectual and technical concepts contained
// herein are proprietary to Last.Backend LLC
// and its suppliers and may be covered by Russian Federation and Foreign Patents,
// patents in process, and are protected by trade secret or copyright law.
// Dissemination of this information or reproduction of this material
// is strictly forbidden unless prior written permission is obtained
// from Last.Backend LLC.
//

package request

import (
	"encoding/json"
	"io"
	"io/ioutil"

	"github.com/lastbackend/lastbackend/pkg/distribution/errors"
	"github.com/lastbackend/lastbackend/pkg/util/validator"
)

type ServiceRequest struct{}

func (ServiceRequest) Manifest() *ServiceManifest {
	return new(ServiceManifest)
}

func (s *ServiceManifest) Validate() *errors.Err {
	switch true {
	case s.Meta.Name != nil && !validator.IsServiceName(*s.Meta.Name):
		return errors.New("service").BadParameter("name")
	case s.Meta.Description != nil && len(*s.Meta.Description) > DEFAULT_DESCRIPTION_LIMIT:
		return errors.New("service").BadParameter("description")
	case len(s.Spec.Template.Containers) == 0:
		return errors.New("service").BadParameter("spec")
	case len(s.Spec.Template.Containers) != 0:
		for _, container := range s.Spec.Template.Containers {
			if len(container.Image.Name) == 0 {
				return errors.New("service").BadParameter("image")
			}
		}
	}

	return nil
}

func (s *ServiceManifest) DecodeAndValidate(reader io.Reader) *errors.Err {

	if reader == nil {
		err := errors.New("data body can not be null")
		return errors.New("service").IncorrectJSON(err)
	}

	body, err := ioutil.ReadAll(reader)
	if err != nil {
		return errors.New("service").Unknown(err)
	}

	err = json.Unmarshal(body, s)
	if err != nil {
		return errors.New("service").IncorrectJSON(err)
	}

	if err := s.Validate(); err != nil {
		return err
	}

	return nil
}

func (ServiceRequest) RemoveOptions() *ServiceRemoveOptions {
	return new(ServiceRemoveOptions)
}

func (s *ServiceRemoveOptions) Validate() *errors.Err {
	return nil
}
<|endoftext|>


<commit_before>/*
Copyright 2015 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 to keep track of API Versions that can be registered and are enabled in api.Scheme.
package registered

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/golang/glog"

	"k8s.io/kubernetes/pkg/api/meta"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/apimachinery"
	"k8s.io/kubernetes/pkg/util/sets"
)

var (
	DefaultAPIRegistrationManager = NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
)

// APIRegistrationManager
type APIRegistrationManager struct {
	// registeredGroupVersions stores all API group versions for which RegisterGroup is called.
	registeredVersions map[unversioned.GroupVersion]struct{}

	// thirdPartyGroupVersions are API versions which are dynamically
	// registered (and unregistered) via API calls to the apiserver
	thirdPartyGroupVersions []unversioned.GroupVersion

	// enabledVersions represents all enabled API versions. It should be a
	// subset of registeredVersions. Please call EnableVersions() to add
	// enabled versions.
	enabledVersions map[unversioned.GroupVersion]struct{}

	// map of group meta for all groups.
	groupMetaMap map[string]*apimachinery.GroupMeta

	// envRequestedVersions represents the versions requested via the
	// KUBE_API_VERSIONS environment variable. The install package of each group
	// checks this list before add their versions to the latest package and
	// Scheme.  This list is small and order matters, so represent as a slice
	envRequestedVersions []unversioned.GroupVersion
}

// NewAPIRegistrationManager constructs a new manager. The argument ought to be
// the value of the KUBE_API_VERSIONS env var, or a value of this which you
// wish to test.
func NewAPIRegistrationManager(kubeAPIVersions string) (*APIRegistrationManager, error) {
	m := &APIRegistrationManager{
		registeredVersions:      map[unversioned.GroupVersion]struct{}{},
		thirdPartyGroupVersions: []unversioned.GroupVersion{},
		enabledVersions:         map[unversioned.GroupVersion]struct{}{},
		groupMetaMap:            map[string]*apimachinery.GroupMeta{},
		envRequestedVersions:    []unversioned.GroupVersion{},
	}

	if len(kubeAPIVersions) != 0 {
		for _, version := range strings.Split(kubeAPIVersions, ",") {
			gv, err := unversioned.ParseGroupVersion(version)
			if err != nil {
				return nil, fmt.Errorf("invalid api version: %s in KUBE_API_VERSIONS: %s.",
					version, kubeAPIVersions)
			}
			m.envRequestedVersions = append(m.envRequestedVersions, gv)
		}
	}
	return m, nil
}

func NewOrDie(kubeAPIVersions string) *APIRegistrationManager {
	m, err := NewAPIRegistrationManager(kubeAPIVersions)
	if err != nil {
		glog.Fatalf("Could not construct version manager: %v (KUBE_API_VERSIONS=%q)", err, kubeAPIVersions)
	}
	return m
}

// People are calling global functions. Let them continue to do that (for now).
var (
	ValidateEnvRequestedVersions  = DefaultAPIRegistrationManager.ValidateEnvRequestedVersions
	AllPreferredGroupVersions     = DefaultAPIRegistrationManager.AllPreferredGroupVersions
	RESTMapper                    = DefaultAPIRegistrationManager.RESTMapper
	GroupOrDie                    = DefaultAPIRegistrationManager.GroupOrDie
	AddThirdPartyAPIGroupVersions = DefaultAPIRegistrationManager.AddThirdPartyAPIGroupVersions
	IsThirdPartyAPIGroupVersion   = DefaultAPIRegistrationManager.IsThirdPartyAPIGroupVersion
	RegisteredGroupVersions       = DefaultAPIRegistrationManager.RegisteredGroupVersions
	IsRegisteredVersion           = DefaultAPIRegistrationManager.IsRegisteredVersion
	IsRegistered                  = DefaultAPIRegistrationManager.IsRegistered
	Group                         = DefaultAPIRegistrationManager.Group
	EnabledVersionsForGroup       = DefaultAPIRegistrationManager.EnabledVersionsForGroup
	EnabledVersions               = DefaultAPIRegistrationManager.EnabledVersions
	IsEnabledVersion              = DefaultAPIRegistrationManager.IsEnabledVersion
	IsAllowedVersion              = DefaultAPIRegistrationManager.IsAllowedVersion
	EnableVersions                = DefaultAPIRegistrationManager.EnableVersions
	RegisterGroup                 = DefaultAPIRegistrationManager.RegisterGroup
	RegisterVersions              = DefaultAPIRegistrationManager.RegisterVersions
)

// RegisterVersions adds the given group versions to the list of registered group versions.
func (m *APIRegistrationManager) RegisterVersions(availableVersions []unversioned.GroupVersion) {
	for _, v := range availableVersions {
		m.registeredVersions[v] = struct{}{}
	}
}

// RegisterGroup adds the given group to the list of registered groups.
func (m *APIRegistrationManager) RegisterGroup(groupMeta apimachinery.GroupMeta) error {
	groupName := groupMeta.GroupVersion.Group
	if _, found := m.groupMetaMap[groupName]; found {
		return fmt.Errorf("group %v is already registered", m.groupMetaMap)
	}
	m.groupMetaMap[groupName] = &groupMeta
	return nil
}

// EnableVersions adds the versions for the given group to the list of enabled versions.
// Note that the caller should call RegisterGroup before calling this method.
// The caller of this function is responsible to add the versions to scheme and RESTMapper.
func (m *APIRegistrationManager) EnableVersions(versions ...unversioned.GroupVersion) error {
	var unregisteredVersions []unversioned.GroupVersion
	for _, v := range versions {
		if _, found := m.registeredVersions[v]; !found {
			unregisteredVersions = append(unregisteredVersions, v)
		}
		m.enabledVersions[v] = struct{}{}
	}
	if len(unregisteredVersions) != 0 {
		return fmt.Errorf("Please register versions before enabling them: %v", unregisteredVersions)
	}
	return nil
}

// IsAllowedVersion returns if the version is allowed by the KUBE_API_VERSIONS
// environment variable. If the environment variable is empty, then it always
// returns true.
func (m *APIRegistrationManager) IsAllowedVersion(v unversioned.GroupVersion) bool {
	if len(m.envRequestedVersions) == 0 {
		return true
	}
	for _, envGV := range m.envRequestedVersions {
		if v == envGV {
			return true
		}
	}
	return false
}

// IsEnabledVersion returns if a version is enabled.
func (m *APIRegistrationManager) IsEnabledVersion(v unversioned.GroupVersion) bool {
	_, found := m.enabledVersions[v]
	return found
}

// EnabledVersions returns all enabled versions.  Groups are randomly ordered, but versions within groups
// are priority order from best to worst
func (m *APIRegistrationManager) EnabledVersions() []unversioned.GroupVersion {
	ret := []unversioned.GroupVersion{}
	for _, groupMeta := range m.groupMetaMap {
		ret = append(ret, groupMeta.GroupVersions...)
	}
	return ret
}

// EnabledVersionsForGroup returns all enabled versions for a group in order of best to worst
func (m *APIRegistrationManager) EnabledVersionsForGroup(group string) []unversioned.GroupVersion {
	groupMeta, ok := m.groupMetaMap[group]
	if !ok {
		return []unversioned.GroupVersion{}
	}

	return append([]unversioned.GroupVersion{}, groupMeta.GroupVersions...)
}

// Group returns the metadata of a group if the group is registered, otherwise
// an error is returned.
func (m *APIRegistrationManager) Group(group string) (*apimachinery.GroupMeta, error) {
	groupMeta, found := m.groupMetaMap[group]
	if !found {
		return nil, fmt.Errorf("group %v has not been registered", group)
	}
	groupMetaCopy := *groupMeta
	return &groupMetaCopy, nil
}

// IsRegistered takes a string and determines if it's one of the registered groups
func (m *APIRegistrationManager) IsRegistered(group string) bool {
	_, found := m.groupMetaMap[group]
	return found
}

// IsRegisteredVersion returns if a version is registered.
func (m *APIRegistrationManager) IsRegisteredVersion(v unversioned.GroupVersion) bool {
	_, found := m.registeredVersions[v]
	return found
}

// RegisteredGroupVersions returns all registered group versions.
func (m *APIRegistrationManager) RegisteredGroupVersions() []unversioned.GroupVersion {
	ret := []unversioned.GroupVersion{}
	for groupVersion := range m.registeredVersions {
		ret = append(ret, groupVersion)
	}
	return ret
}

// IsThirdPartyAPIGroupVersion returns true if the api version is a user-registered group/version.
func (m *APIRegistrationManager) IsThirdPartyAPIGroupVersion(gv unversioned.GroupVersion) bool {
	for ix := range m.thirdPartyGroupVersions {
		if m.thirdPartyGroupVersions[ix] == gv {
			return true
		}
	}
	return false
}

// AddThirdPartyAPIGroupVersions sets the list of third party versions,
// registers them in the API machinery and enables them.
// Skips GroupVersions that are already registered.
// Returns the list of GroupVersions that were skipped.
func (m *APIRegistrationManager) AddThirdPartyAPIGroupVersions(gvs ...unversioned.GroupVersion) []unversioned.GroupVersion {
	filteredGVs := []unversioned.GroupVersion{}
	skippedGVs := []unversioned.GroupVersion{}
	for ix := range gvs {
		if !m.IsRegisteredVersion(gvs[ix]) {
			filteredGVs = append(filteredGVs, gvs[ix])
		} else {
			glog.V(3).Infof("Skipping %s, because its already registered", gvs[ix].String())
			skippedGVs = append(skippedGVs, gvs[ix])
		}
	}
	if len(filteredGVs) == 0 {
		return skippedGVs
	}
	m.RegisterVersions(filteredGVs)
	m.EnableVersions(filteredGVs...)
	m.thirdPartyGroupVersions = append(m.thirdPartyGroupVersions, filteredGVs...)

	return skippedGVs
}

// TODO: This is an expedient function, because we don't check if a Group is
// supported throughout the code base. We will abandon this function and
// checking the error returned by the Group() function.
func (m *APIRegistrationManager) GroupOrDie(group string) *apimachinery.GroupMeta {
	groupMeta, found := m.groupMetaMap[group]
	if !found {
		if group == "" {
			panic("The legacy v1 API is not registered.")
		} else {
			panic(fmt.Sprintf("Group %s is not registered.", group))
		}
	}
	groupMetaCopy := *groupMeta
	return &groupMetaCopy
}

// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
//  1. if KUBE_API_VERSIONS is specified, then KUBE_API_VERSIONS in order, OR
//  1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
//     kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
//     all other groups alphabetical.
func (m *APIRegistrationManager) RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper {
	unionMapper := meta.MultiRESTMapper{}
	unionedGroups := sets.NewString()
	for enabledVersion := range m.enabledVersions {
		if !unionedGroups.Has(enabledVersion.Group) {
			unionedGroups.Insert(enabledVersion.Group)
			groupMeta := m.groupMetaMap[enabledVersion.Group]
			unionMapper = append(unionMapper, groupMeta.RESTMapper)
		}
	}

	if len(versionPatterns) != 0 {
		resourcePriority := []unversioned.GroupVersionResource{}
		kindPriority := []unversioned.GroupVersionKind{}
		for _, versionPriority := range versionPatterns {
			resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
			kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
		}

		return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
	}

	if len(m.envRequestedVersions) != 0 {
		resourcePriority := []unversioned.GroupVersionResource{}
		kindPriority := []unversioned.GroupVersionKind{}

		for _, versionPriority := range m.envRequestedVersions {
			resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
			kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
		}

		return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
	}

	prioritizedGroups := []string{"", "extensions", "metrics"}
	resourcePriority, kindPriority := m.prioritiesForGroups(prioritizedGroups...)

	prioritizedGroupsSet := sets.NewString(prioritizedGroups...)
	remainingGroups := sets.String{}
	for enabledVersion := range m.enabledVersions {
		if !prioritizedGroupsSet.Has(enabledVersion.Group) {
			remainingGroups.Insert(enabledVersion.Group)
		}
	}

	remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...)
	resourcePriority = append(resourcePriority, remainingResourcePriority...)
	kindPriority = append(kindPriority, remainingKindPriority...)

	return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}

// prioritiesForGroups returns the resource and kind priorities for a PriorityRESTMapper, preferring the preferred version of each group first,
// then any non-preferred version of the group second.
func (m *APIRegistrationManager) prioritiesForGroups(groups ...string) ([]unversioned.GroupVersionResource, []unversioned.GroupVersionKind) {
	resourcePriority := []unversioned.GroupVersionResource{}
	kindPriority := []unversioned.GroupVersionKind{}

	for _, group := range groups {
		availableVersions := m.EnabledVersionsForGroup(group)
		if len(availableVersions) > 0 {
			resourcePriority = append(resourcePriority, availableVersions[0].WithResource(meta.AnyResource))
			kindPriority = append(kindPriority, availableVersions[0].WithKind(meta.AnyKind))
		}
	}
	for _, group := range groups {
		resourcePriority = append(resourcePriority, unversioned.GroupVersionResource{Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource})
		kindPriority = append(kindPriority, unversioned.GroupVersionKind{Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind})
	}

	return resourcePriority, kindPriority
}

// AllPreferredGroupVersions returns the preferred versions of all registered
// groups in the form of "group1/version1,group2/version2,..."
func (m *APIRegistrationManager) AllPreferredGroupVersions() string {
	if len(m.groupMetaMap) == 0 {
		return ""
	}
	var defaults []string
	for _, groupMeta := range m.groupMetaMap {
		defaults = append(defaults, groupMeta.GroupVersion.String())
	}
	sort.Strings(defaults)
	return strings.Join(defaults, ",")
}

// ValidateEnvRequestedVersions returns a list of versions that are requested in
// the KUBE_API_VERSIONS environment variable, but not enabled.
func (m *APIRegistrationManager) ValidateEnvRequestedVersions() []unversioned.GroupVersion {
	var missingVersions []unversioned.GroupVersion
	for _, v := range m.envRequestedVersions {
		if _, found := m.enabledVersions[v]; !found {
			missingVersions = append(missingVersions, v)
		}
	}
	return missingVersions
}
<commit_msg>filter enabled versions by enablement<commit_after>/*
Copyright 2015 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 to keep track of API Versions that can be registered and are enabled in api.Scheme.
package registered

import (
	"fmt"
	"os"
	"sort"
	"strings"

	"github.com/golang/glog"

	"k8s.io/kubernetes/pkg/api/meta"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/apimachinery"
	"k8s.io/kubernetes/pkg/util/sets"
)

var (
	DefaultAPIRegistrationManager = NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
)

// APIRegistrationManager
type APIRegistrationManager struct {
	// registeredGroupVersions stores all API group versions for which RegisterGroup is called.
	registeredVersions map[unversioned.GroupVersion]struct{}

	// thirdPartyGroupVersions are API versions which are dynamically
	// registered (and unregistered) via API calls to the apiserver
	thirdPartyGroupVersions []unversioned.GroupVersion

	// enabledVersions represents all enabled API versions. It should be a
	// subset of registeredVersions. Please call EnableVersions() to add
	// enabled versions.
	enabledVersions map[unversioned.GroupVersion]struct{}

	// map of group meta for all groups.
	groupMetaMap map[string]*apimachinery.GroupMeta

	// envRequestedVersions represents the versions requested via the
	// KUBE_API_VERSIONS environment variable. The install package of each group
	// checks this list before add their versions to the latest package and
	// Scheme.  This list is small and order matters, so represent as a slice
	envRequestedVersions []unversioned.GroupVersion
}

// NewAPIRegistrationManager constructs a new manager. The argument ought to be
// the value of the KUBE_API_VERSIONS env var, or a value of this which you
// wish to test.
func NewAPIRegistrationManager(kubeAPIVersions string) (*APIRegistrationManager, error) {
	m := &APIRegistrationManager{
		registeredVersions:      map[unversioned.GroupVersion]struct{}{},
		thirdPartyGroupVersions: []unversioned.GroupVersion{},
		enabledVersions:         map[unversioned.GroupVersion]struct{}{},
		groupMetaMap:            map[string]*apimachinery.GroupMeta{},
		envRequestedVersions:    []unversioned.GroupVersion{},
	}

	if len(kubeAPIVersions) != 0 {
		for _, version := range strings.Split(kubeAPIVersions, ",") {
			gv, err := unversioned.ParseGroupVersion(version)
			if err != nil {
				return nil, fmt.Errorf("invalid api version: %s in KUBE_API_VERSIONS: %s.",
					version, kubeAPIVersions)
			}
			m.envRequestedVersions = append(m.envRequestedVersions, gv)
		}
	}
	return m, nil
}

func NewOrDie(kubeAPIVersions string) *APIRegistrationManager {
	m, err := NewAPIRegistrationManager(kubeAPIVersions)
	if err != nil {
		glog.Fatalf("Could not construct version manager: %v (KUBE_API_VERSIONS=%q)", err, kubeAPIVersions)
	}
	return m
}

// People are calling global functions. Let them continue to do that (for now).
var (
	ValidateEnvRequestedVersions  = DefaultAPIRegistrationManager.ValidateEnvRequestedVersions
	AllPreferredGroupVersions     = DefaultAPIRegistrationManager.AllPreferredGroupVersions
	RESTMapper                    = DefaultAPIRegistrationManager.RESTMapper
	GroupOrDie                    = DefaultAPIRegistrationManager.GroupOrDie
	AddThirdPartyAPIGroupVersions = DefaultAPIRegistrationManager.AddThirdPartyAPIGroupVersions
	IsThirdPartyAPIGroupVersion   = DefaultAPIRegistrationManager.IsThirdPartyAPIGroupVersion
	RegisteredGroupVersions       = DefaultAPIRegistrationManager.RegisteredGroupVersions
	IsRegisteredVersion           = DefaultAPIRegistrationManager.IsRegisteredVersion
	IsRegistered                  = DefaultAPIRegistrationManager.IsRegistered
	Group                         = DefaultAPIRegistrationManager.Group
	EnabledVersionsForGroup       = DefaultAPIRegistrationManager.EnabledVersionsForGroup
	EnabledVersions               = DefaultAPIRegistrationManager.EnabledVersions
	IsEnabledVersion              = DefaultAPIRegistrationManager.IsEnabledVersion
	IsAllowedVersion              = DefaultAPIRegistrationManager.IsAllowedVersion
	EnableVersions                = DefaultAPIRegistrationManager.EnableVersions
	RegisterGroup                 = DefaultAPIRegistrationManager.RegisterGroup
	RegisterVersions              = DefaultAPIRegistrationManager.RegisterVersions
)

// RegisterVersions adds the given group versions to the list of registered group versions.
func (m *APIRegistrationManager) RegisterVersions(availableVersions []unversioned.GroupVersion) {
	for _, v := range availableVersions {
		m.registeredVersions[v] = struct{}{}
	}
}

// RegisterGroup adds the given group to the list of registered groups.
func (m *APIRegistrationManager) RegisterGroup(groupMeta apimachinery.GroupMeta) error {
	groupName := groupMeta.GroupVersion.Group
	if _, found := m.groupMetaMap[groupName]; found {
		return fmt.Errorf("group %v is already registered", m.groupMetaMap)
	}
	m.groupMetaMap[groupName] = &groupMeta
	return nil
}

// EnableVersions adds the versions for the given group to the list of enabled versions.
// Note that the caller should call RegisterGroup before calling this method.
// The caller of this function is responsible to add the versions to scheme and RESTMapper.
func (m *APIRegistrationManager) EnableVersions(versions ...unversioned.GroupVersion) error {
	var unregisteredVersions []unversioned.GroupVersion
	for _, v := range versions {
		if _, found := m.registeredVersions[v]; !found {
			unregisteredVersions = append(unregisteredVersions, v)
		}
		m.enabledVersions[v] = struct{}{}
	}
	if len(unregisteredVersions) != 0 {
		return fmt.Errorf("Please register versions before enabling them: %v", unregisteredVersions)
	}
	return nil
}

// IsAllowedVersion returns if the version is allowed by the KUBE_API_VERSIONS
// environment variable. If the environment variable is empty, then it always
// returns true.
func (m *APIRegistrationManager) IsAllowedVersion(v unversioned.GroupVersion) bool {
	if len(m.envRequestedVersions) == 0 {
		return true
	}
	for _, envGV := range m.envRequestedVersions {
		if v == envGV {
			return true
		}
	}
	return false
}

// IsEnabledVersion returns if a version is enabled.
func (m *APIRegistrationManager) IsEnabledVersion(v unversioned.GroupVersion) bool {
	_, found := m.enabledVersions[v]
	return found
}

// EnabledVersions returns all enabled versions.  Groups are randomly ordered, but versions within groups
// are priority order from best to worst
func (m *APIRegistrationManager) EnabledVersions() []unversioned.GroupVersion {
	ret := []unversioned.GroupVersion{}
	for _, groupMeta := range m.groupMetaMap {
		for _, version := range groupMeta.GroupVersions {
			if m.IsEnabledVersion(version) {
				ret = append(ret, version)
			}
		}
	}
	return ret
}

// EnabledVersionsForGroup returns all enabled versions for a group in order of best to worst
func (m *APIRegistrationManager) EnabledVersionsForGroup(group string) []unversioned.GroupVersion {
	groupMeta, ok := m.groupMetaMap[group]
	if !ok {
		return []unversioned.GroupVersion{}
	}

	ret := []unversioned.GroupVersion{}
	for _, version := range groupMeta.GroupVersions {
		if m.IsEnabledVersion(version) {
			ret = append(ret, version)
		}
	}
	return ret
}

// Group returns the metadata of a group if the group is registered, otherwise
// an error is returned.
func (m *APIRegistrationManager) Group(group string) (*apimachinery.GroupMeta, error) {
	groupMeta, found := m.groupMetaMap[group]
	if !found {
		return nil, fmt.Errorf("group %v has not been registered", group)
	}
	groupMetaCopy := *groupMeta
	return &groupMetaCopy, nil
}

// IsRegistered takes a string and determines if it's one of the registered groups
func (m *APIRegistrationManager) IsRegistered(group string) bool {
	_, found := m.groupMetaMap[group]
	return found
}

// IsRegisteredVersion returns if a version is registered.
func (m *APIRegistrationManager) IsRegisteredVersion(v unversioned.GroupVersion) bool {
	_, found := m.registeredVersions[v]
	return found
}

// RegisteredGroupVersions returns all registered group versions.
func (m *APIRegistrationManager) RegisteredGroupVersions() []unversioned.GroupVersion {
	ret := []unversioned.GroupVersion{}
	for groupVersion := range m.registeredVersions {
		ret = append(ret, groupVersion)
	}
	return ret
}

// IsThirdPartyAPIGroupVersion returns true if the api version is a user-registered group/version.
func (m *APIRegistrationManager) IsThirdPartyAPIGroupVersion(gv unversioned.GroupVersion) bool {
	for ix := range m.thirdPartyGroupVersions {
		if m.thirdPartyGroupVersions[ix] == gv {
			return true
		}
	}
	return false
}

// AddThirdPartyAPIGroupVersions sets the list of third party versions,
// registers them in the API machinery and enables them.
// Skips GroupVersions that are already registered.
// Returns the list of GroupVersions that were skipped.
func (m *APIRegistrationManager) AddThirdPartyAPIGroupVersions(gvs ...unversioned.GroupVersion) []unversioned.GroupVersion {
	filteredGVs := []unversioned.GroupVersion{}
	skippedGVs := []unversioned.GroupVersion{}
	for ix := range gvs {
		if !m.IsRegisteredVersion(gvs[ix]) {
			filteredGVs = append(filteredGVs, gvs[ix])
		} else {
			glog.V(3).Infof("Skipping %s, because its already registered", gvs[ix].String())
			skippedGVs = append(skippedGVs, gvs[ix])
		}
	}
	if len(filteredGVs) == 0 {
		return skippedGVs
	}
	m.RegisterVersions(filteredGVs)
	m.EnableVersions(filteredGVs...)
	m.thirdPartyGroupVersions = append(m.thirdPartyGroupVersions, filteredGVs...)

	return skippedGVs
}

// TODO: This is an expedient function, because we don't check if a Group is
// supported throughout the code base. We will abandon this function and
// checking the error returned by the Group() function.
func (m *APIRegistrationManager) GroupOrDie(group string) *apimachinery.GroupMeta {
	groupMeta, found := m.groupMetaMap[group]
	if !found {
		if group == "" {
			panic("The legacy v1 API is not registered.")
		} else {
			panic(fmt.Sprintf("Group %s is not registered.", group))
		}
	}
	groupMetaCopy := *groupMeta
	return &groupMetaCopy
}

// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
//  1. if KUBE_API_VERSIONS is specified, then KUBE_API_VERSIONS in order, OR
//  1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
//     kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
//     all other groups alphabetical.
func (m *APIRegistrationManager) RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper {
	unionMapper := meta.MultiRESTMapper{}
	unionedGroups := sets.NewString()
	for enabledVersion := range m.enabledVersions {
		if !unionedGroups.Has(enabledVersion.Group) {
			unionedGroups.Insert(enabledVersion.Group)
			groupMeta := m.groupMetaMap[enabledVersion.Group]
			unionMapper = append(unionMapper, groupMeta.RESTMapper)
		}
	}

	if len(versionPatterns) != 0 {
		resourcePriority := []unversioned.GroupVersionResource{}
		kindPriority := []unversioned.GroupVersionKind{}
		for _, versionPriority := range versionPatterns {
			resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
			kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
		}

		return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
	}

	if len(m.envRequestedVersions) != 0 {
		resourcePriority := []unversioned.GroupVersionResource{}
		kindPriority := []unversioned.GroupVersionKind{}

		for _, versionPriority := range m.envRequestedVersions {
			resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
			kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
		}

		return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
	}

	prioritizedGroups := []string{"", "extensions", "metrics"}
	resourcePriority, kindPriority := m.prioritiesForGroups(prioritizedGroups...)

	prioritizedGroupsSet := sets.NewString(prioritizedGroups...)
	remainingGroups := sets.String{}
	for enabledVersion := range m.enabledVersions {
		if !prioritizedGroupsSet.Has(enabledVersion.Group) {
			remainingGroups.Insert(enabledVersion.Group)
		}
	}

	remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...)
	resourcePriority = append(resourcePriority, remainingResourcePriority...)
	kindPriority = append(kindPriority, remainingKindPriority...)

	return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}

// prioritiesForGroups returns the resource and kind priorities for a PriorityRESTMapper, preferring the preferred version of each group first,
// then any non-preferred version of the group second.
func (m *APIRegistrationManager) prioritiesForGroups(groups ...string) ([]unversioned.GroupVersionResource, []unversioned.GroupVersionKind) {
	resourcePriority := []unversioned.GroupVersionResource{}
	kindPriority := []unversioned.GroupVersionKind{}

	for _, group := range groups {
		availableVersions := m.EnabledVersionsForGroup(group)
		if len(availableVersions) > 0 {
			resourcePriority = append(resourcePriority, availableVersions[0].WithResource(meta.AnyResource))
			kindPriority = append(kindPriority, availableVersions[0].WithKind(meta.AnyKind))
		}
	}
	for _, group := range groups {
		resourcePriority = append(resourcePriority, unversioned.GroupVersionResource{Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource})
		kindPriority = append(kindPriority, unversioned.GroupVersionKind{Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind})
	}

	return resourcePriority, kindPriority
}

// AllPreferredGroupVersions returns the preferred versions of all registered
// groups in the form of "group1/version1,group2/version2,..."
func (m *APIRegistrationManager) AllPreferredGroupVersions() string {
	if len(m.groupMetaMap) == 0 {
		return ""
	}
	var defaults []string
	for _, groupMeta := range m.groupMetaMap {
		defaults = append(defaults, groupMeta.GroupVersion.String())
	}
	sort.Strings(defaults)
	return strings.Join(defaults, ",")
}

// ValidateEnvRequestedVersions returns a list of versions that are requested in
// the KUBE_API_VERSIONS environment variable, but not enabled.
func (m *APIRegistrationManager) ValidateEnvRequestedVersions() []unversioned.GroupVersion {
	var missingVersions []unversioned.GroupVersion
	for _, v := range m.envRequestedVersions {
		if _, found := m.enabledVersions[v]; !found {
			missingVersions = append(missingVersions, v)
		}
	}
	return missingVersions
}
<|endoftext|>


<commit_before>package generic

import (
	"bytes"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"testing"

	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/openshift/origin/pkg/build/api"
)

var mockBuildStrategy = api.BuildStrategy{
	Type: "STI",
	STIStrategy: &api.STIBuildStrategy{
		From: &kapi.ObjectReference{
			Name: "repository/image",
		},
	},
}

func GivenRequest(method string) *http.Request {
	req, _ := http.NewRequest(method, "http://someurl.com", nil)
	return req
}

func GivenRequestWithPayload(t *testing.T, filename string) *http.Request {
	data, err := ioutil.ReadFile("fixtures/" + filename)
	if err != nil {
		t.Errorf("Error reading setup data: %v", err)
		return nil
	}
	req, _ := http.NewRequest("POST", "http://someurl.com", bytes.NewReader(data))
	req.Header.Add("User-Agent", "Some User Agent")
	req.Header.Add("Content-Type", "application/json")
	return req
}

func GivenRequestWithRefsPayload(t *testing.T) *http.Request {
	data, err := ioutil.ReadFile("fixtures/post-receive-git.json")
	if err != nil {
		t.Errorf("Error reading setup data: %v", err)
		return nil
	}
	req, _ := http.NewRequest("POST", "http://someurl.com", bytes.NewReader(data))
	req.Header.Add("User-Agent", "Some User Agent")
	req.Header.Add("Content-Type", "application/json")
	return req
}

func TestVerifyRequestForMethod(t *testing.T) {
	req := GivenRequest("GET")
	err := verifyRequest(req)
	if err == nil || !strings.Contains(err.Error(), "method") {
		t.Errorf("Expected anything but POST to be an invalid method %v", err)
	}
}

func TestVerifyRequestForUserAgent(t *testing.T) {
	req := &http.Request{
		Header: http.Header{"Content-Type": {"application/json"}},
		Method: "POST",
	}
	err := verifyRequest(req)
	if err != nil {
		t.Errorf("unexpected error %v", err)
	}

	req.Header.Add("User-Agent", "")
	err = verifyRequest(req)
	if err != nil {
		t.Errorf("unexpected error %v", err)
	}

	req.Header.Set("User-Agent", "foobar")
	err = verifyRequest(req)
	if err != nil {
		t.Errorf("unexpected error %v", err)
	}

}

func TestExtractWithEmptyPayload(t *testing.T) {
	req := GivenRequest("POST")
	req.Header.Add("User-Agent", "Some User Agent")
	req.Header.Add("Content-Type", "application/json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "master",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)
	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}

func TestExtractWithUnmatchedRefGitPayload(t *testing.T) {
	req := GivenRequestWithPayload(t, "push-github.json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "asdfkasdfasdfasdfadsfkjhkhkh",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	build, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Unexpected error when triggering build: %v", err)
	}
	if proceed {
		t.Error("Expected 'proceed' return value to be 'false' for unmatched refs")
	}
	if build != nil {
		t.Error("Expected the 'revision' return value to be nil since we arent creating a new one")
	}
}

func TestExtractWithGitPayload(t *testing.T) {
	req := GivenRequestWithPayload(t, "push-github.json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "master",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()

	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision == nil {
		t.Error("Expected the 'revision' return value to not be nil")
	}
}

func TestExtractWithGitRefsPayload(t *testing.T) {
	req := GivenRequestWithRefsPayload(t)
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "master",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()

	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision == nil {
		t.Error("Expected the 'revision' return value to not be nil")
	}
}

func TestExtractWithUnmatchedGitRefsPayload(t *testing.T) {
	req := GivenRequestWithRefsPayload(t)
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "other",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if proceed {
		t.Error("Expected 'proceed' return value to be 'false'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}

func TestGitlabPush(t *testing.T) {
	req := GivenRequestWithPayload(t, "push-gitlab.json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()

	_, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
}
func TestNonJsonPush(t *testing.T) {
	req, _ := http.NewRequest("POST", "http://someurl.com", nil)
	req.Header.Add("User-Agent", "Some User Agent")
	req.Header.Add("Content-Type", "*/*")

	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()

	_, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
}

type errJSON struct{}

func (*errJSON) Read(p []byte) (n int, err error) {
	p = []byte("{")
	return len(p), io.EOF
}

func TestExtractWithUnmarshalError(t *testing.T) {
	req, _ := http.NewRequest("POST", "http://someurl.com", &errJSON{})
	req.Header.Add("User-Agent", "Some User Agent")
	req.Header.Add("Content-Type", "application/json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)
	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}
<commit_msg>Updated tests for generic webhook<commit_after>package generic

import (
	"bytes"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"testing"

	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/openshift/origin/pkg/build/api"
	"github.com/openshift/origin/pkg/build/webhook"
)

var mockBuildStrategy = api.BuildStrategy{
	Type: "STI",
	STIStrategy: &api.STIBuildStrategy{
		From: &kapi.ObjectReference{
			Name: "repository/image",
		},
	},
}

func GivenRequest(method string) *http.Request {
	req, _ := http.NewRequest(method, "http://someurl.com", nil)
	return req
}

func GivenRequestWithPayload(t *testing.T, filename string) *http.Request {
	data, err := ioutil.ReadFile("fixtures/" + filename)
	if err != nil {
		t.Errorf("Error reading setup data: %v", err)
		return nil
	}
	req, _ := http.NewRequest("POST", "http://someurl.com", bytes.NewReader(data))
	req.Header.Add("Content-Type", "application/json")
	return req
}

func GivenRequestWithRefsPayload(t *testing.T) *http.Request {
	data, err := ioutil.ReadFile("fixtures/post-receive-git.json")
	if err != nil {
		t.Errorf("Error reading setup data: %v", err)
		return nil
	}
	req, _ := http.NewRequest("POST", "http://someurl.com", bytes.NewReader(data))
	req.Header.Add("Content-Type", "application/json")
	return req
}

func TestVerifyRequestForMethod(t *testing.T) {
	req := GivenRequest("GET")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err == nil || !strings.Contains(err.Error(), "Unsupported HTTP method") {
		t.Errorf("Excepcted unsupported HTTP method, got %v!", err)
	}
	if proceed {
		t.Error("Expected 'proceed' return value to be 'false'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}

func TestWrongSecret(t *testing.T) {
	req := GivenRequest("POST")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "wrongsecret", "", req)

	if err != webhook.ErrSecretMismatch {
		t.Errorf("Excepcted %v, got %v!", webhook.ErrSecretMismatch, err)
	}
	if proceed {
		t.Error("Expected 'proceed' return value to be 'false'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}

type emptyReader struct{}

func (_ emptyReader) Read(p []byte) (n int, err error) {
	return 0, io.EOF
}

func TestExtractWithEmptyPayload(t *testing.T) {
	req, _ := http.NewRequest("POST", "http://someurl.com", emptyReader{})
	req.Header.Add("Content-Type", "application/json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "master",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)
	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}

func TestExtractWithUnmatchedRefGitPayload(t *testing.T) {
	req := GivenRequestWithPayload(t, "push-github.json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "asdfkasdfasdfasdfadsfkjhkhkh",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	build, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Unexpected error when triggering build: %v", err)
	}
	if proceed {
		t.Error("Expected 'proceed' return value to be 'false' for unmatched refs")
	}
	if build != nil {
		t.Error("Expected the 'revision' return value to be nil since we arent creating a new one")
	}
}

func TestExtractWithGitPayload(t *testing.T) {
	req := GivenRequestWithPayload(t, "push-github.json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "master",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision == nil {
		t.Error("Expected the 'revision' return value to not be nil")
	}
}

func TestExtractWithGitRefsPayload(t *testing.T) {
	req := GivenRequestWithRefsPayload(t)
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "master",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision == nil {
		t.Error("Expected the 'revision' return value to not be nil")
	}
}

func TestExtractWithUnmatchedGitRefsPayload(t *testing.T) {
	req := GivenRequestWithRefsPayload(t)
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "other",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if proceed {
		t.Error("Expected 'proceed' return value to be 'false'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}

func TestGitlabPush(t *testing.T) {
	req := GivenRequestWithPayload(t, "push-gitlab.json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	_, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
}
func TestNonJsonPush(t *testing.T) {
	req, _ := http.NewRequest("POST", "http://someurl.com", nil)
	req.Header.Add("Content-Type", "*/*")

	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	_, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)

	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
}

type errJSON struct{}

func (_ errJSON) Read(p []byte) (n int, err error) {
	p = []byte("{")
	return len(p), io.EOF
}

func TestExtractWithUnmarshalError(t *testing.T) {
	req, _ := http.NewRequest("POST", "http://someurl.com", errJSON{})
	req.Header.Add("Content-Type", "application/json")
	buildConfig := &api.BuildConfig{
		Triggers: []api.BuildTriggerPolicy{
			{
				Type: api.GenericWebHookBuildTriggerType,
				GenericWebHook: &api.WebHookTrigger{
					Secret: "secret100",
				},
			},
		},
		Parameters: api.BuildParameters{
			Source: api.BuildSource{
				Type: api.BuildSourceGit,
				Git: &api.GitBuildSource{
					Ref: "other",
				},
			},
			Strategy: mockBuildStrategy,
		},
	}
	plugin := New()
	revision, proceed, err := plugin.Extract(buildConfig, "secret100", "", req)
	if err != nil {
		t.Errorf("Expected to be able to trigger a build without a payload error: %v", err)
	}
	if !proceed {
		t.Error("Expected 'proceed' return value to be 'true'")
	}
	if revision != nil {
		t.Error("Expected the 'revision' return value to be nil")
	}
}
<|endoftext|>