<commit_before>package acme

import (
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/miekg/dns"
)

type preCheckDNSFunc func(domain, fqdn string) bool

var preCheckDNS preCheckDNSFunc = checkDNS

var preCheckDNSFallbackCount = 5

// DNS01Record returns a DNS record which will fulfill the `dns-01` challenge
func DNS01Record(domain, keyAuth string) (fqdn string, value string, ttl int) {
	keyAuthShaBytes := sha256.Sum256([]byte(keyAuth))
	// base64URL encoding without padding
	keyAuthSha := base64.URLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])
	value = strings.TrimRight(keyAuthSha, "=")
	ttl = 120
	fqdn = fmt.Sprintf("_acme-challenge.%s.", domain)
	return
}

// dnsChallenge implements the dns-01 challenge according to ACME 7.5
type dnsChallenge struct {
	jws      *jws
	validate validateFunc
	provider ChallengeProvider
}

func (s *dnsChallenge) Solve(chlng challenge, domain string) error {

	logf("[INFO] acme: Trying to solve DNS-01")

	if s.provider == nil {
		return errors.New("No DNS Provider configured")
	}

	// Generate the Key Authorization for the challenge
	keyAuth, err := getKeyAuthorization(chlng.Token, &s.jws.privKey.PublicKey)
	if err != nil {
		return err
	}

	err = s.provider.Present(domain, chlng.Token, keyAuth)
	if err != nil {
		return fmt.Errorf("Error presenting token %s", err)
	}
	defer func() {
		err := s.provider.CleanUp(domain, chlng.Token, keyAuth)
		if err != nil {
			log.Printf("Error cleaning up %s %v ", domain, err)
		}
	}()

	fqdn, _, _ := DNS01Record(domain, keyAuth)

	preCheckDNS(domain, fqdn)

	return s.validate(s.jws, domain, chlng.URI, challenge{Resource: "challenge", Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth})
}

func checkDNS(domain, fqdn string) bool {
	// check if the expected DNS entry was created. If not wait for some time and try again.
	m := new(dns.Msg)
	m.SetQuestion(domain+".", dns.TypeSOA)
	c := new(dns.Client)
	in, _, err := c.Exchange(m, "8.8.8.8:53")
	if err != nil {
		return false
	}

	var authorativeNS string
	for _, answ := range in.Answer {
		soa := answ.(*dns.SOA)
		authorativeNS = soa.Ns
	}

	fallbackCnt := 0
	for fallbackCnt < preCheckDNSFallbackCount {
		m.SetQuestion(fqdn, dns.TypeTXT)
		in, _, err = c.Exchange(m, authorativeNS+":53")
		if err != nil {
			return false
		}

		if len(in.Answer) > 0 {
			return true
		}

		fallbackCnt++
		if fallbackCnt >= preCheckDNSFallbackCount {
			return false
		}

		time.Sleep(time.Second * time.Duration(fallbackCnt))
	}

	return false
}

// toFqdn converts the name into a fqdn appending a trailing dot.
func toFqdn(name string) string {
	n := len(name)
	if n == 0 || name[n-1] == '.' {
		return name
	}
	return name + "."
}

// unFqdn converts the fqdn into a name removing the trailing dot.
func unFqdn(name string) string {
	n := len(name)
	if n != 0 && name[n-1] == '.' {
		return name[:n-1]
	}
	return name
}
<commit_msg>Add missing domain name for consistency<commit_after>package acme

import (
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/miekg/dns"
)

type preCheckDNSFunc func(domain, fqdn string) bool

var preCheckDNS preCheckDNSFunc = checkDNS

var preCheckDNSFallbackCount = 5

// DNS01Record returns a DNS record which will fulfill the `dns-01` challenge
func DNS01Record(domain, keyAuth string) (fqdn string, value string, ttl int) {
	keyAuthShaBytes := sha256.Sum256([]byte(keyAuth))
	// base64URL encoding without padding
	keyAuthSha := base64.URLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])
	value = strings.TrimRight(keyAuthSha, "=")
	ttl = 120
	fqdn = fmt.Sprintf("_acme-challenge.%s.", domain)
	return
}

// dnsChallenge implements the dns-01 challenge according to ACME 7.5
type dnsChallenge struct {
	jws      *jws
	validate validateFunc
	provider ChallengeProvider
}

func (s *dnsChallenge) Solve(chlng challenge, domain string) error {
	logf("[INFO][%s] acme: Trying to solve DNS-01", domain)

	if s.provider == nil {
		return errors.New("No DNS Provider configured")
	}

	// Generate the Key Authorization for the challenge
	keyAuth, err := getKeyAuthorization(chlng.Token, &s.jws.privKey.PublicKey)
	if err != nil {
		return err
	}

	err = s.provider.Present(domain, chlng.Token, keyAuth)
	if err != nil {
		return fmt.Errorf("Error presenting token %s", err)
	}
	defer func() {
		err := s.provider.CleanUp(domain, chlng.Token, keyAuth)
		if err != nil {
			log.Printf("Error cleaning up %s %v ", domain, err)
		}
	}()

	fqdn, _, _ := DNS01Record(domain, keyAuth)

	preCheckDNS(domain, fqdn)

	return s.validate(s.jws, domain, chlng.URI, challenge{Resource: "challenge", Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth})
}

func checkDNS(domain, fqdn string) bool {
	// check if the expected DNS entry was created. If not wait for some time and try again.
	m := new(dns.Msg)
	m.SetQuestion(domain+".", dns.TypeSOA)
	c := new(dns.Client)
	in, _, err := c.Exchange(m, "8.8.8.8:53")
	if err != nil {
		return false
	}

	var authorativeNS string
	for _, answ := range in.Answer {
		soa := answ.(*dns.SOA)
		authorativeNS = soa.Ns
	}

	fallbackCnt := 0
	for fallbackCnt < preCheckDNSFallbackCount {
		m.SetQuestion(fqdn, dns.TypeTXT)
		in, _, err = c.Exchange(m, authorativeNS+":53")
		if err != nil {
			return false
		}

		if len(in.Answer) > 0 {
			return true
		}

		fallbackCnt++
		if fallbackCnt >= preCheckDNSFallbackCount {
			return false
		}

		time.Sleep(time.Second * time.Duration(fallbackCnt))
	}

	return false
}

// toFqdn converts the name into a fqdn appending a trailing dot.
func toFqdn(name string) string {
	n := len(name)
	if n == 0 || name[n-1] == '.' {
		return name
	}
	return name + "."
}

// unFqdn converts the fqdn into a name removing the trailing dot.
func unFqdn(name string) string {
	n := len(name)
	if n != 0 && name[n-1] == '.' {
		return name[:n-1]
	}
	return name
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"time"
)

func main() {
	for _, arg := range os.Args[1:] {
		fmt.Println("address was " + arg)
		fetch(arg)
	}
}

func fetch(arg string) {
	start := time.Now()
	response, err := http.Get(arg)
	if err != nil {
		fmt.Printf("ERROR %s\n", err)
		return
	}
	contents, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Printf("ERROR %s\n", err)
		return
	}
	fmt.Printf("%s\n", string(contents))
	elapsed := time.Since(start)
	fmt.Printf("%dnS\n", elapsed.Nanoseconds())
}
<commit_msg>Simple client to put load on a web server<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strconv"
	"sync"
	"time"
)

func main() {
	address := os.Args[1]
	concurrencycount, err := strconv.Atoi(os.Args[2])
	if err != nil {
		fmt.Printf("ERROR %s\n", err)
		return
	}
	requestcount, err := strconv.Atoi(os.Args[3])
	if err != nil {
		fmt.Printf("ERROR %s\n", err)
		return
	}
	fmt.Printf("Will spawn %d workers each making %d requests to %s\n", concurrencycount, requestcount, address)
	runLoadTest(address, requestcount, concurrencycount)
}

func runLoadTest(url string, requestcount int, concurrencycount int) {
	totalRequests := requestcount * concurrencycount
	ch := make(chan string, totalRequests)
	var wg sync.WaitGroup
	for i := 0; i < concurrencycount; i++ {
		wg.Add(1)
		go fetch(url, requestcount, ch, &wg)
	}
	fmt.Println("Waiting for results…")

	completedRequests := 0
	for completedRequests < totalRequests {
		_ = <-ch
		completedRequests++
		fmt.Printf("\r%.2f%% done (%d requests out of %d)", (float64(completedRequests)/float64(totalRequests))*100.0, completedRequests, totalRequests)
	}
	wg.Wait()
	fmt.Printf("\nYay🎈\n")

}

func fetch(address string, requestcount int, ch chan string, wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Printf("Fetching %s %d times\n", address, requestcount)
	for i := 0; i < requestcount; i++ {
		start := time.Now()
		response, err := http.Get(address)
		if err != nil {
			fmt.Printf("ERROR %s\n", err)
			return
		}
		_, err = ioutil.ReadAll(response.Body)
		if err != nil {
			fmt.Printf("ERROR %s\n", err)
			return
		}
		//fmt.Printf("%s\n", string(contents))
		elapsed := time.Since(start)
		ch <- fmt.Sprintf("%d", elapsed.Nanoseconds())
	}

}
<|endoftext|>


<commit_before>package controllers

import (
	"encoding/json"
	"xcfg-server/models"

	"github.com/astaxie/beego"
)

type AuthController struct {
	beego.Controller
}

//登录
func (c *AuthController) Login() {
	data := 0
	uservm := models.UserLoginViewModel{}
	json.Unmarshal(c.Ctx.Input.RequestBody, &uservm)
	if uservm.Un==""{
		c.ParseForm(&uservm)
	}
	if user := models.Login(uservm.Un, uservm.Pwd); user.Id > 0 {
		data = 1
		c.Ctx.SetCookie("adAuthCookie", "true")
		c.Ctx.SetCookie("loginUser", user.Name)
		c.SetSession("userId", user.Id)
	}
	jsonResult := models.JsonResult{Code: 200, Data: data}
	c.Data["json"] = &jsonResult
	c.ServeJSON()
}

func (c *AuthController) GetMenus() {
	un := c.Ctx.GetCookie("loginUser")
	if un == "admin" {
		menus := models.GetMenus()
		jsonResult := models.JsonResult{200, menus, ""}
		c.Data["json"] = &jsonResult
	} else {
		id := c.GetSession("userId").(int)
		roles := models.GetRolesByUserId(id)
		menuIds := []int{}
		for _, v := range roles {
			rms := models.GetMenusByRoleId(v.RoleId)
			for _, rm := range rms {
				menuIds = append(menuIds, rm.MenuId)
			}
		}
		menus := models.GetMenusByMenuIds(menuIds)
		jsonResult := models.JsonResult{200, menus, ""}
		c.Data["json"] = &jsonResult
	}
	c.ServeJSON()
}

func (c *AuthController) CheckPwd() {
	data := 0
	uservm := models.UserModViewModel{}
	json.Unmarshal(c.Ctx.Input.RequestBody, &uservm)
	id := c.GetSession("userId").(int)
	if user := models.GetUser(id); user.Pwd == uservm.OldPwd {
		data = 1
	}
	jsonResult := models.JsonResult{Code: 200, Data: data}
	c.Data["json"] = &jsonResult
	c.ServeJSON()
}

func (c *AuthController) ModPwd() {
	data := 0
	uservm := models.UserModViewModel{}
	json.Unmarshal(c.Ctx.Input.RequestBody, &uservm)
	id := c.GetSession("userId").(int)
	if models.UpdatePwd(id, uservm.Pwd) {
		data = 1
	}
	jsonResult := models.JsonResult{Code: 200, Data: data}
	c.Data["json"] = &jsonResult
	c.ServeJSON()
}
<commit_msg>form support<commit_after>package controllers

import (
	"encoding/json"
	"xcfg-server/models"

	"github.com/astaxie/beego"
)

type AuthController struct {
	beego.Controller
}

//登录
func (c *AuthController) Login() {
	data := 0
	uservm := models.UserLoginViewModel{}
	json.Unmarshal(c.Ctx.Input.RequestBody, &uservm)
	if uservm.Un==""{
		c.ParseForm(&uservm)
	}
	if user := models.Login(uservm.Un, uservm.Pwd); user.Id > 0 {
		data = 1
		c.Ctx.SetCookie("adAuthCookie", "true")
		c.Ctx.SetCookie("loginUser", user.Name)
		c.SetSession("userId", user.Id)
	}
	jsonResult := models.JsonResult{Code: 200, Data: data}
	c.Data["json"] = &jsonResult
	c.ServeJSON()
}

func (c *AuthController) GetMenus() {
	un := c.Ctx.GetCookie("loginUser")
	if un == "admin" {
		menus := models.GetMenus()
		jsonResult := models.JsonResult{200, menus, ""}
		c.Data["json"] = &jsonResult
	} else {
		id := c.GetSession("userId").(int)
		roles := models.GetRolesByUserId(id)
		menuIds := []int{}
		for _, v := range roles {
			rms := models.GetMenusByRoleId(v.RoleId)
			for _, rm := range rms {
				menuIds = append(menuIds, rm.MenuId)
			}
		}
		menus := models.GetMenusByMenuIds(menuIds)
		jsonResult := models.JsonResult{200, menus, ""}
		c.Data["json"] = &jsonResult
	}
	c.ServeJSON()
}

func (c *AuthController) CheckPwd() {
	data := 0
	uservm := models.UserModViewModel{}
	json.Unmarshal(c.Ctx.Input.RequestBody, &uservm)
	if uservm.OldPwd==""{
		c.ParseForm(&uservm)
	}
	id := c.GetSession("userId").(int)
	if  user := models.GetUser(id); user.Pwd == uservm.OldPwd {
		data = 1
	}
	jsonResult := models.JsonResult{Code: 200, Data: data}
	c.Data["json"] = &jsonResult
	c.ServeJSON()
}

func (c *AuthController) ModPwd() {
	data := 0
	uservm := models.UserModViewModel{}
	json.Unmarshal(c.Ctx.Input.RequestBody, &uservm)
	if uservm.OldPwd==""{
		c.ParseForm(&uservm)
	}
	//
	id := c.GetSession("userId").(int)
	if models.UpdatePwd(id, uservm.Pwd) {
		data = 1
	}
	jsonResult := models.JsonResult{Code: 200, Data: data}
	c.Data["json"] = &jsonResult
	c.ServeJSON()
}
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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 e2e

import (
	"fmt"
	"os/exec"
	"regexp"
	"strings"

	"github.com/golang/glog"
)

func createGCEStaticIP(name string) (string, error) {
	// gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// abshah@abhidesk:~/go/src/code.google.com/p/google-api-go-client/compute/v1$ gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// Created [https://www.googleapis.com/compute/v1/projects/abshah-kubernetes-001/regions/us-central1/addresses/test-static-ip].
	// NAME           REGION      ADDRESS       STATUS
	// test-static-ip us-central1 104.197.143.7 RESERVED

	output, err := exec.Command("gcloud", "compute", "addresses", "create",
		name, "--project", testContext.CloudConfig.ProjectID,
		"--region", "us-central1", "-q").CombinedOutput()
	if err != nil {
		return "", err
	}
	glog.Errorf("Creating static IP with name:%s in project: %s", name, testContext.CloudConfig.ProjectID)
	text := string(output)
	if strings.Contains(text, "RESERVED") {
		r, _ := regexp.Compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")
		staticIP := r.FindString(text)
		if staticIP == "" {
			glog.Errorf("Static IP creation output is \n %s", text)
			return "", fmt.Errorf("Static IP not found in gcloud compute command output")
		} else {
			return staticIP, nil
		}
	} else {
		return "", fmt.Errorf("Static IP Could not be reserved.")
	}
}

func deleteGCEStaticIP(name string) error {
	// gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// abshah@abhidesk:~/go/src/code.google.com/p/google-api-go-client/compute/v1$ gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// Created [https://www.googleapis.com/compute/v1/projects/abshah-kubernetes-001/regions/us-central1/addresses/test-static-ip].
	// NAME           REGION      ADDRESS       STATUS
	// test-static-ip us-central1 104.197.143.7 RESERVED

	_, err := exec.Command("gcloud", "compute", "addresses", "delete",
		name, "--project", testContext.CloudConfig.ProjectID,
		"--region", "us-central1", "-q").CombinedOutput()
	return err
}
<commit_msg>add more prints<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

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 e2e

import (
	"fmt"
	"os/exec"
	"regexp"
	"strings"

	"github.com/golang/glog"
)

func createGCEStaticIP(name string) (string, error) {
	// gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// abshah@abhidesk:~/go/src/code.google.com/p/google-api-go-client/compute/v1$ gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// Created [https://www.googleapis.com/compute/v1/projects/abshah-kubernetes-001/regions/us-central1/addresses/test-static-ip].
	// NAME           REGION      ADDRESS       STATUS
	// test-static-ip us-central1 104.197.143.7 RESERVED

	output, err := exec.Command("gcloud", "compute", "addresses", "create",
		name, "--project", testContext.CloudConfig.ProjectID,
		"--region", "us-central1", "-q").CombinedOutput()
	if err != nil {
		glog.Errorf("Creating static IP with name:%s in project: %s", name, testContext.CloudConfig.ProjectID)
		glog.Errorf("output: %s", output)
		return "", err
	}
	glog.Errorf("Creating static IP with name:%s in project: %s", name, testContext.CloudConfig.ProjectID)
	text := string(output)
	if strings.Contains(text, "RESERVED") {
		r, _ := regexp.Compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")
		staticIP := r.FindString(text)
		if staticIP == "" {
			glog.Errorf("Static IP creation output is \n %s", text)
			return "", fmt.Errorf("Static IP not found in gcloud compute command output")
		} else {
			return staticIP, nil
		}
	} else {
		return "", fmt.Errorf("Static IP Could not be reserved.")
	}
}

func deleteGCEStaticIP(name string) error {
	// gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// abshah@abhidesk:~/go/src/code.google.com/p/google-api-go-client/compute/v1$ gcloud compute --project "abshah-kubernetes-001" addresses create "test-static-ip" --region "us-central1"
	// Created [https://www.googleapis.com/compute/v1/projects/abshah-kubernetes-001/regions/us-central1/addresses/test-static-ip].
	// NAME           REGION      ADDRESS       STATUS
	// test-static-ip us-central1 104.197.143.7 RESERVED

	_, err := exec.Command("gcloud", "compute", "addresses", "delete",
		name, "--project", testContext.CloudConfig.ProjectID,
		"--region", "us-central1", "-q").CombinedOutput()
	return err
}
<|endoftext|>


<commit_before>package checkdisk

import (
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"
	gpud "github.com/shirou/gopsutil/disk"
)

var opts struct {
	Warning  *string `short:"w" long:"warning" value-name:"N, N%" description:"Exit with WARNING status if less than N units or N% of disk are free"`
	Critical *string `short:"c" long:"critical" value-name:"N, N%" description:"Exit with CRITICAL status if less than N units or N% of disk are free"`
	Path     *string `short:"p" long:"path" value-name:"PATH" description:"Mount point or block device as emitted by the mount(8) command"`
	Exclude  *string `short:"x" long:"exclude_device" value-name:"EXCLUDE PATH" description:"Ignore device (only works if -p unspecified)"`
	Units    *string `short:"u" long:"units" value-name:"STRING" description:"Choose bytes, kB, MB, GB, TB (default: MB)"`
}

const (
	b  = float64(1)
	kb = float64(1024) * b
	mb = float64(1024) * kb
	gb = float64(1024) * mb
	tb = float64(1024) * gb
)

type unit struct {
	Name string
	Size float64
}

func checkStatus(current checkers.Status, threshold string, units float64, disk *gpud.UsageStat, status checkers.Status) (checkers.Status, error) {
	if strings.HasSuffix(threshold, "%") {
		v, err := strconv.ParseFloat(strings.TrimRight(threshold, "%"), 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		freePct := float64(100) - disk.UsedPercent
		inodesFreePct := float64(100) - disk.InodesUsedPercent

		if v > freePct || v > inodesFreePct {
			current = status
		}
	} else {
		v, err := strconv.ParseFloat(threshold, 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		if v > float64(disk.Free) {
			current = status
		}
	}

	return current, nil
}

func genMessage(disk *gpud.UsageStat, u unit) string {
	all := float64(disk.Total) / u.Size
	used := float64(disk.Used) / u.Size
	free := float64(disk.Free) / u.Size
	freePct := float64(100) - disk.UsedPercent
	inodesFreePct := float64(100) - disk.InodesUsedPercent

	return fmt.Sprintf("Path: %v, All: %.2f %v, Used: %.2f %v, Free: %.2f %v, Free percentage: %.2f (inodes: %.2f)", disk.Path, all, u.Name, used, u.Name, free, u.Name, freePct, inodesFreePct)
}

// Do the plugin
func Do() {
	ckr := run(os.Args[1:])
	ckr.Name = "Disk"
	ckr.Exit()
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	partitions, err := listPartitions()
	if err != nil {
		return checkers.Unknown(fmt.Sprintf("Faild to fetch partitions: %s", err))
	}

	if opts.Path != nil {
		exist := false
		for _, partition := range partitions {
			if *opts.Path == partition.Mountpoint {
				partitions = []gpud.PartitionStat{partition}
				exist = true
				break
			}
		}

		if !exist {
			return checkers.Unknown(fmt.Sprintf("Faild to fetch mountpoint: %s", errors.New("Invalid argument flag '-p, --path'")))
		}
	}

	if opts.Path == nil && opts.Exclude != nil {
		var tmp []gpud.PartitionStat
		for _, partition := range partitions {
			if *opts.Exclude != partition.Mountpoint {
				tmp = append(tmp, partition)
			}
		}
		partitions = tmp
	}

	var disks []*gpud.UsageStat

	for _, partition := range partitions {
		disk, err := gpud.Usage(partition.Mountpoint)
		if err != nil {
			return checkers.Unknown(fmt.Sprintf("Faild to fetch disk usage: %s", err))
		}

		disks = append(disks, disk)
	}

	u := unit{"MB", mb}
	if opts.Units != nil {
		us := strings.ToLower(*opts.Units)
		if us == "bytes" {
			u = unit{us, b}
		} else if us == "kb" {
			u = unit{us, mb}
		} else if us == "gb" {
			u = unit{us, gb}
		} else if us == "tb" {
			u = unit{us, tb}
		} else {
			return checkers.Unknown(fmt.Sprintf("Faild to check disk status: %s", errors.New("Invalid argument flag '-u, --units'")))
		}
	}

	checkSt := checkers.OK
	if opts.Warning != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Warning, u.Size, disk, checkers.WARNING)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Faild to check disk status: %s", err))
			}

			if checkSt == checkers.WARNING {
				break
			}
		}
	}

	if opts.Critical != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Critical, u.Size, disk, checkers.CRITICAL)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Faild to check disk status: %s", err))
			}

			if checkSt == checkers.CRITICAL {
				break
			}
		}
	}

	var msgs []string
	for _, disk := range disks {
		msg := genMessage(disk, u)
		msgs = append(msgs, msg)
	}
	msgss := strings.Join(msgs, ";\n")

	return checkers.NewChecker(checkSt, msgss)
}

// ref: mountlist.c in gnulib
// https://github.com/coreutils/gnulib/blob/a742bdb3/lib/mountlist.c#L168
func listPartitions() ([]gpud.PartitionStat, error) {
	allPartitions, err := gpud.Partitions(true)
	if err != nil {
		return nil, err
	}
	partitions := make([]gpud.PartitionStat, 0, len(allPartitions))
	for _, p := range allPartitions {
		switch p.Fstype {
		case "autofs":
		case "proc":
		case "subfs":
		case "debugfs":
		case "devpts":
		case "fusectl":
		case "mqueue":
		case "rpc_pipefs":
		case "sysfs":
		case "devfs":
		case "kernfs":
		case "ignore":
			continue
		case "none":
			if !strings.Contains(p.Opts, "bind") {
				partitions = append(partitions, p)
			}
		default:
			partitions = append(partitions, p)
		}
	}
	return partitions, nil
}
<commit_msg>[check-disk] multiple cases switch statement<commit_after>package checkdisk

import (
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"
	gpud "github.com/shirou/gopsutil/disk"
)

var opts struct {
	Warning  *string `short:"w" long:"warning" value-name:"N, N%" description:"Exit with WARNING status if less than N units or N% of disk are free"`
	Critical *string `short:"c" long:"critical" value-name:"N, N%" description:"Exit with CRITICAL status if less than N units or N% of disk are free"`
	Path     *string `short:"p" long:"path" value-name:"PATH" description:"Mount point or block device as emitted by the mount(8) command"`
	Exclude  *string `short:"x" long:"exclude_device" value-name:"EXCLUDE PATH" description:"Ignore device (only works if -p unspecified)"`
	Units    *string `short:"u" long:"units" value-name:"STRING" description:"Choose bytes, kB, MB, GB, TB (default: MB)"`
}

const (
	b  = float64(1)
	kb = float64(1024) * b
	mb = float64(1024) * kb
	gb = float64(1024) * mb
	tb = float64(1024) * gb
)

type unit struct {
	Name string
	Size float64
}

func checkStatus(current checkers.Status, threshold string, units float64, disk *gpud.UsageStat, status checkers.Status) (checkers.Status, error) {
	if strings.HasSuffix(threshold, "%") {
		v, err := strconv.ParseFloat(strings.TrimRight(threshold, "%"), 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		freePct := float64(100) - disk.UsedPercent
		inodesFreePct := float64(100) - disk.InodesUsedPercent

		if v > freePct || v > inodesFreePct {
			current = status
		}
	} else {
		v, err := strconv.ParseFloat(threshold, 64)
		if err != nil {
			return checkers.UNKNOWN, err
		}

		if v > float64(disk.Free) {
			current = status
		}
	}

	return current, nil
}

func genMessage(disk *gpud.UsageStat, u unit) string {
	all := float64(disk.Total) / u.Size
	used := float64(disk.Used) / u.Size
	free := float64(disk.Free) / u.Size
	freePct := float64(100) - disk.UsedPercent
	inodesFreePct := float64(100) - disk.InodesUsedPercent

	return fmt.Sprintf("Path: %v, All: %.2f %v, Used: %.2f %v, Free: %.2f %v, Free percentage: %.2f (inodes: %.2f)", disk.Path, all, u.Name, used, u.Name, free, u.Name, freePct, inodesFreePct)
}

// Do the plugin
func Do() {
	ckr := run(os.Args[1:])
	ckr.Name = "Disk"
	ckr.Exit()
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	partitions, err := listPartitions()
	if err != nil {
		return checkers.Unknown(fmt.Sprintf("Faild to fetch partitions: %s", err))
	}

	if opts.Path != nil {
		exist := false
		for _, partition := range partitions {
			if *opts.Path == partition.Mountpoint {
				partitions = []gpud.PartitionStat{partition}
				exist = true
				break
			}
		}

		if !exist {
			return checkers.Unknown(fmt.Sprintf("Faild to fetch mountpoint: %s", errors.New("Invalid argument flag '-p, --path'")))
		}
	}

	if opts.Path == nil && opts.Exclude != nil {
		var tmp []gpud.PartitionStat
		for _, partition := range partitions {
			if *opts.Exclude != partition.Mountpoint {
				tmp = append(tmp, partition)
			}
		}
		partitions = tmp
	}

	var disks []*gpud.UsageStat

	for _, partition := range partitions {
		disk, err := gpud.Usage(partition.Mountpoint)
		if err != nil {
			return checkers.Unknown(fmt.Sprintf("Faild to fetch disk usage: %s", err))
		}

		disks = append(disks, disk)
	}

	u := unit{"MB", mb}
	if opts.Units != nil {
		us := strings.ToLower(*opts.Units)
		if us == "bytes" {
			u = unit{us, b}
		} else if us == "kb" {
			u = unit{us, mb}
		} else if us == "gb" {
			u = unit{us, gb}
		} else if us == "tb" {
			u = unit{us, tb}
		} else {
			return checkers.Unknown(fmt.Sprintf("Faild to check disk status: %s", errors.New("Invalid argument flag '-u, --units'")))
		}
	}

	checkSt := checkers.OK
	if opts.Warning != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Warning, u.Size, disk, checkers.WARNING)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Faild to check disk status: %s", err))
			}

			if checkSt == checkers.WARNING {
				break
			}
		}
	}

	if opts.Critical != nil {
		for _, disk := range disks {
			checkSt, err = checkStatus(checkSt, *opts.Critical, u.Size, disk, checkers.CRITICAL)
			if err != nil {
				return checkers.Unknown(fmt.Sprintf("Faild to check disk status: %s", err))
			}

			if checkSt == checkers.CRITICAL {
				break
			}
		}
	}

	var msgs []string
	for _, disk := range disks {
		msg := genMessage(disk, u)
		msgs = append(msgs, msg)
	}
	msgss := strings.Join(msgs, ";\n")

	return checkers.NewChecker(checkSt, msgss)
}

// ref: mountlist.c in gnulib
// https://github.com/coreutils/gnulib/blob/a742bdb3/lib/mountlist.c#L168
func listPartitions() ([]gpud.PartitionStat, error) {
	allPartitions, err := gpud.Partitions(true)
	if err != nil {
		return nil, err
	}
	partitions := make([]gpud.PartitionStat, 0, len(allPartitions))
	for _, p := range allPartitions {
		switch p.Fstype {
		case "autofs",
			"proc",
			"subfs",
			"debugfs",
			"devpts",
			"fusectl",
			"mqueue",
			"rpc_pipefs",
			"sysfs",
			"devfs",
			"kernfs",
			"ignore":
			continue
		case "none":
			if !strings.Contains(p.Opts, "bind") {
				partitions = append(partitions, p)
			}
		default:
			partitions = append(partitions, p)
		}
	}
	return partitions, nil
}
<|endoftext|>


<commit_before>// Copyright 2017 The WPT Dashboard Project. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package compute

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"

	"github.com/w3c/wptdashboard/metrics"
	"github.com/w3c/wptdashboard/shared"
)

var timeA = time.Unix(0, 0)
var timeB = time.Unix(0, 1)

func TestGatherResultsById_TwoRuns_SameTest(t *testing.T) {
	runA := shared.TestRun{
		"ABrowser",
		"1.0",
		"MyOS",
		"1.0",
		"abcd",
		"http://example.com/a_run.json",
		timeA,
	}
	runB := shared.TestRun{
		"BBrowser",
		"1.0",
		"MyOS",
		"1.0",
		"dcba",
		"http://example.com/b_run.json",
		timeB,
	}
	testName := "Do a thing"
	results := &[]metrics.TestRunResults{
		{
			&runA,
			&metrics.TestResults{
				"A test",
				"OK",
				&testName,
				[]metrics.SubTest{},
			},
		},
		{
			&runB,
			&metrics.TestResults{
				"A test",
				"ERROR",
				&testName,
				[]metrics.SubTest{},
			},
		},
	}
	gathered := GatherResultsById(results)
	assert.Equal(t, 1, len(gathered)) // Merged to single TestId: {"A test",""}.
	for testId, runStatusMap := range gathered {
		assert.Equal(t, testId, metrics.TestId{"A test", ""})
		assert.Equal(t, 2, len(runStatusMap))
		assert.Equal(t, runStatusMap[runA], metrics.CompleteTestStatus{
			metrics.TestStatus_fromString("OK"),
			metrics.SubTestStatus_fromString("STATUS_UNKNOWN"),
		})
		assert.Equal(t, runStatusMap[runB], metrics.CompleteTestStatus{
			metrics.TestStatus_fromString("ERROR"),
			metrics.SubTestStatus_fromString("STATUS_UNKNOWN"),
		})
	}
}
<commit_msg>Fix more assert.*() calls: (t, expected, actual)<commit_after>// Copyright 2017 The WPT Dashboard Project. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package compute

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"

	"github.com/w3c/wptdashboard/metrics"
	"github.com/w3c/wptdashboard/shared"
)

var timeA = time.Unix(0, 0)
var timeB = time.Unix(0, 1)

func TestGatherResultsById_TwoRuns_SameTest(t *testing.T) {
	runA := shared.TestRun{
		"ABrowser",
		"1.0",
		"MyOS",
		"1.0",
		"abcd",
		"http://example.com/a_run.json",
		timeA,
	}
	runB := shared.TestRun{
		"BBrowser",
		"1.0",
		"MyOS",
		"1.0",
		"dcba",
		"http://example.com/b_run.json",
		timeB,
	}
	testName := "Do a thing"
	results := &[]metrics.TestRunResults{
		{
			&runA,
			&metrics.TestResults{
				"A test",
				"OK",
				&testName,
				[]metrics.SubTest{},
			},
		},
		{
			&runB,
			&metrics.TestResults{
				"A test",
				"ERROR",
				&testName,
				[]metrics.SubTest{},
			},
		},
	}
	gathered := GatherResultsById(results)
	assert.Equal(t, 1, len(gathered)) // Merged to single TestId: {"A test",""}.
	for testId, runStatusMap := range gathered {
		assert.Equal(t, metrics.TestId{"A test", ""}, testId)
		assert.Equal(t, 2, len(runStatusMap))
		assert.Equal(t, metrics.CompleteTestStatus{
			metrics.TestStatus_fromString("OK"),
			metrics.SubTestStatus_fromString("STATUS_UNKNOWN"),
		}, runStatusMap[runA])
		assert.Equal(t, metrics.CompleteTestStatus{
			metrics.TestStatus_fromString("ERROR"),
			metrics.SubTestStatus_fromString("STATUS_UNKNOWN"),
		}, runStatusMap[runB])
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ses"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsSesNotification() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSesNotificationSet,
		Read:   resourceAwsSesNotificationRead,
		Update: resourceAwsSesNotificationSet,
		Delete: resourceAwsSesNotificationDelete,

		Schema: map[string]*schema.Schema{
			"topic_arn": &schema.Schema{
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"notification_type": &schema.Schema{
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateNotificationType,
			},

			"identity": &schema.Schema{
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateIdentity,
			},
		},
	}
}

func resourceAwsSesNotificationSet(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sesConn
	topic := d.Get("topic_arn").(string)
	notification := d.Get("notification_type").(string)
	identity := d.Get("identity").(string)

	setOpts := &ses.SetIdentityNotificationTopicInput{
		Identity:         aws.String(identity),
		NotificationType: aws.String(notification),
		SnsTopic:         aws.String(topic),
	}

	log.Printf("[DEBUG] Setting SES Identity Notification: %#v", setOpts)

	if _, err := conn.SetIdentityNotificationTopic(setOpts); err != nil {
		return fmt.Errorf("Error setting SES Identity Notification: %s", err)
	}

	return resourceAwsSesNotificationRead(d, meta)
}

func resourceAwsSesNotificationRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sesConn
	notification := d.Get("notification_type").(string)
	identity := d.Get("identity").(string)

	getOpts := &ses.GetIdentityNotificationAttributesInput{
		Identities: []*string{aws.String(identity)},
	}

	log.Printf("[DEBUG] Reading SES Identity Notification Attributes: %#v", getOpts)

	response, err := conn.GetIdentityNotificationAttributes(getOpts)

	if err != nil {
		return fmt.Errorf("Error reading SES Identity Notification: %s", err)
	}

	notificationAttributes := response.NotificationAttributes[identity]
	switch notification {
	case ses.NotificationTypeBounce:
		if err := d.Set("topic_arn", notificationAttributes.BounceTopic); err != nil {
			return err
		}
	case ses.NotificationTypeComplaint:
		if err := d.Set("topic_arn", notificationAttributes.ComplaintTopic); err != nil {
			return err
		}
	case ses.NotificationTypeDelivery:
		if err := d.Set("topic_arn", notificationAttributes.DeliveryTopic); err != nil {
			return err
		}
	}

	return nil
}

func resourceAwsSesNotificationDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sesConn
	notification := d.Get("notification_type").(string)
	identity := d.Get("identity").(string)

	setOpts := &ses.SetIdentityNotificationTopicInput{
		Identity:         aws.String(identity),
		NotificationType: aws.String(notification),
		SnsTopic:         nil,
	}

	log.Printf("[DEBUG] Deleting SES Identity Notification: %#v", setOpts)

	if _, err := conn.SetIdentityNotificationTopic(setOpts); err != nil {
		return fmt.Errorf("Error deleting SES Identity Notification: %s", err)
	}

	return resourceAwsSesNotificationRead(d, meta)
}

func validateNotificationType(v interface{}, k string) (ws []string, errors []error) {
	value := strings.Title(strings.ToLower(v.(string)))
	if value == "Bounce" || value == "Complaint" || value == "Delivery" {
		return
	}

	errors = append(errors, fmt.Errorf("%q must be either %q, %q or %q", k, "Bounce", "Complaint", "Delivery"))
	return
}

func validateIdentity(v interface{}, k string) (ws []string, errors []error) {
	value := strings.ToLower(v.(string))
	if value != "" {
		return
	}

	errors = append(errors, fmt.Errorf("%q must not be empty", k))
	return
}
<commit_msg>#931 Fixing minor nitpicks<commit_after>package aws

import (
	"fmt"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ses"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsSesNotification() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsSesNotificationSet,
		Read:   resourceAwsSesNotificationRead,
		Update: resourceAwsSesNotificationSet,
		Delete: resourceAwsSesNotificationDelete,

		Schema: map[string]*schema.Schema{
			"topic_arn": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateArn,
			},

			"notification_type": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: ValidateFunc: validation.StringInSlice([]string{
					ses.NotificationTypeBounce,
					ses.NotificationTypeComplaint,
					ses.NotificationTypeDelivery,
				}, false),
			},

			"identity": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validation.NoZeroValues,
			},
		},
	}
}

func resourceAwsSesNotificationSet(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sesConn
	topic := d.Get("topic_arn").(string)
	notification := d.Get("notification_type").(string)
	identity := d.Get("identity").(string)

	setOpts := &ses.SetIdentityNotificationTopicInput{
		Identity:         aws.String(identity),
		NotificationType: aws.String(notification),
		SnsTopic:         aws.String(topic),
	}

	log.Printf("[DEBUG] Setting SES Identity Notification: %#v", setOpts)

	if _, err := conn.SetIdentityNotificationTopic(setOpts); err != nil {
		return fmt.Errorf("Error setting SES Identity Notification: %s", err)
	}

	return resourceAwsSesNotificationRead(d, meta)
}

func resourceAwsSesNotificationRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sesConn
	notification := d.Get("notification_type").(string)
	identity := d.Get("identity").(string)

	getOpts := &ses.GetIdentityNotificationAttributesInput{
		Identities: []*string{aws.String(identity)},
	}

	log.Printf("[DEBUG] Reading SES Identity Notification Attributes: %#v", getOpts)

	response, err := conn.GetIdentityNotificationAttributes(getOpts)

	if err != nil {
		return fmt.Errorf("Error reading SES Identity Notification: %s", err)
	}

	notificationAttributes := response.NotificationAttributes[identity]
	switch notification {
	case ses.NotificationTypeBounce:
		if err := d.Set("topic_arn", notificationAttributes.BounceTopic); err != nil {
			return err
		}
	case ses.NotificationTypeComplaint:
		if err := d.Set("topic_arn", notificationAttributes.ComplaintTopic); err != nil {
			return err
		}
	case ses.NotificationTypeDelivery:
		if err := d.Set("topic_arn", notificationAttributes.DeliveryTopic); err != nil {
			return err
		}
	}

	return nil
}

func resourceAwsSesNotificationDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).sesConn
	notification := d.Get("notification_type").(string)
	identity := d.Get("identity").(string)

	setOpts := &ses.SetIdentityNotificationTopicInput{
		Identity:         aws.String(identity),
		NotificationType: aws.String(notification),
		SnsTopic:         nil,
	}

	log.Printf("[DEBUG] Deleting SES Identity Notification: %#v", setOpts)

	if _, err := conn.SetIdentityNotificationTopic(setOpts); err != nil {
		return fmt.Errorf("Error deleting SES Identity Notification: %s", err)
	}

	return resourceAwsSesNotificationRead(d, meta)
}<|endoftext|>


<commit_before>//go:build integ
// +build integ

// Copyright Istio 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 security

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

	"istio.io/istio/pkg/http/headers"
	"istio.io/istio/pkg/test"
	echoClient "istio.io/istio/pkg/test/echo"
	"istio.io/istio/pkg/test/env"
	"istio.io/istio/pkg/test/framework"
	"istio.io/istio/pkg/test/framework/components/echo"
	"istio.io/istio/pkg/test/framework/components/echo/check"
	"istio.io/istio/pkg/test/framework/components/echo/echotest"
	"istio.io/istio/pkg/test/framework/components/echo/match"
	"istio.io/istio/pkg/test/framework/components/istio"
	"istio.io/istio/pkg/test/framework/components/namespace"
	"istio.io/istio/pkg/test/framework/resource"
	"istio.io/istio/pkg/test/util/file"
	ingressutil "istio.io/istio/tests/integration/security/sds_ingress/util"
	sdstlsutil "istio.io/istio/tests/integration/security/sds_tls_origination/util"
)

// TestSimpleTlsOrigination test SIMPLE TLS mode with TLS origination happening at Gateway proxy
// It uses CredentialName set in DestinationRule API to fetch secrets from k8s API server
func TestSimpleTlsOrigination(t *testing.T) {
	// nolint: staticcheck
	framework.NewTest(t).
		RequiresSingleNetwork(). // https://github.com/istio/istio/issues/37134
		Features("security.egress.tls.sds").
		Run(func(t framework.TestContext) {
			var (
				credName        = "tls-credential-cacert"
				fakeCredName    = "fake-tls-credential-cacert"
				credNameMissing = "tls-credential-not-created-cacert"
			)

			credentialA := ingressutil.IngressCredential{
				CaCert: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}
			CredentialB := ingressutil.IngressCredential{
				CaCert: sdstlsutil.FakeRoot,
			}
			// Add kubernetes secret to provision key/cert for gateway.
			ingressutil.CreateIngressKubeSecret(t, credName, ingressutil.TLS, credentialA, false)

			// Add kubernetes secret to provision key/cert for gateway.
			ingressutil.CreateIngressKubeSecret(t, fakeCredName, ingressutil.TLS, CredentialB, false)

			// Set up Host Namespace
			host := apps.External.All.Config().ClusterLocalFQDN()

			testCases := []struct {
				name            string
				statusCode      int
				credentialToUse string
				useGateway      bool
			}{
				// Use CA certificate stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance.
				{
					name:            "simple",
					statusCode:      http.StatusOK,
					credentialToUse: strings.TrimSuffix(credName, "-cacert"),
					useGateway:      true,
				},
				// Use CA certificate stored as k8s secret with different issuing CA as server's CA.
				// This root certificate cannot validate the server cert presented by the echoboot server instance.
				{
					name:            "fake root",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(fakeCredName, "-cacert"),
					useGateway:      false,
				},

				// Set up an UpstreamCluster with a CredentialName when secret doesn't even exist in istio-system ns.
				// Secret fetching error at Gateway, results in a 503 response.
				{
					name:            "missing secret",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(credNameMissing, "-cacert"),
					useGateway:      false,
				},
			}

			newTLSGateway(t, t, apps.Ns1.Namespace, apps.External.All)
			for _, tc := range testCases {
				t.NewSubTest(tc.name).Run(func(t framework.TestContext) {
					newTLSGatewayDestinationRule(t, apps.External.All, "SIMPLE", tc.credentialToUse)
					newTLSGatewayTest(t).
						Run(func(t framework.TestContext, from echo.Instance, to echo.Target) {
							callOpt := newTLSGatewayCallOpts(to, host, tc.statusCode, tc.useGateway)
							from.CallOrFail(t, callOpt)
						})
				})
			}
		})
}

// TestMutualTlsOrigination test MUTUAL TLS mode with TLS origination happening at Gateway proxy
// It uses CredentialName set in DestinationRule API to fetch secrets from k8s API server
func TestMutualTlsOrigination(t *testing.T) {
	// nolint: staticcheck
	framework.NewTest(t).
		RequiresSingleNetwork(). // https://github.com/istio/istio/issues/37134
		Features("security.egress.mtls.sds").
		Run(func(t framework.TestContext) {
			var (
				credNameGeneric    = "mtls-credential-generic"
				credNameNotGeneric = "mtls-credential-not-generic"
				fakeCredNameA      = "fake-mtls-credential-a"
				fakeCredNameB      = "fake-mtls-credential-b"
				credNameMissing    = "mtls-credential-not-created"
				simpleCredName     = "tls-credential-simple-cacert"
			)

			// Add kubernetes secret to provision key/cert for gateway.

			ingressutil.CreateIngressKubeSecret(t, credNameGeneric, ingressutil.Mtls, ingressutil.IngressCredential{
				Certificate: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/cert-chain.pem")),
				PrivateKey:  file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/key.pem")),
				CaCert:      file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, false)

			ingressutil.CreateIngressKubeSecret(t, credNameNotGeneric, ingressutil.Mtls, ingressutil.IngressCredential{
				Certificate: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/cert-chain.pem")),
				PrivateKey:  file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/key.pem")),
				CaCert:      file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, true)

			// Configured with an invalid ClientCert
			ingressutil.CreateIngressKubeSecret(t, fakeCredNameA, ingressutil.Mtls, ingressutil.IngressCredential{
				Certificate: sdstlsutil.FakeCert,
				PrivateKey:  file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/key.pem")),
				CaCert:      file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, false)

			// Configured with an invalid ClientCert and PrivateKey
			ingressutil.CreateIngressKubeSecret(t, fakeCredNameB, ingressutil.Mtls, ingressutil.IngressCredential{
				Certificate: sdstlsutil.FakeCert,
				PrivateKey:  sdstlsutil.FakeKey,
				CaCert:      file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, false)

			ingressutil.CreateIngressKubeSecret(t, simpleCredName, ingressutil.TLS, ingressutil.IngressCredential{
				CaCert: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, false)

			// Set up Host Namespace
			host := apps.External.All.Config().ClusterLocalFQDN()

			testCases := []struct {
				name            string
				statusCode      int
				credentialToUse string
				useGateway      bool
			}{
				// Use CA certificate and client certs stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance and server CA can
				// validate the client cert. Secret is of type generic.
				{
					name:            "generic",
					statusCode:      http.StatusOK,
					credentialToUse: strings.TrimSuffix(credNameGeneric, "-cacert"),
					useGateway:      true,
				},
				// Use CA certificate and client certs stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance and server CA can
				// validate the client cert. Secret is not of type generic.
				{
					name:            "non-generic",
					statusCode:      http.StatusOK,
					credentialToUse: strings.TrimSuffix(credNameNotGeneric, "-cacert"),
					useGateway:      true,
				},
				// Use CA certificate and client certs stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance and server CA
				// cannot validate the client cert. Returns 503 response as TLS handshake fails.
				{
					name:            "invalid client cert",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(fakeCredNameA, "-cacert"),
					useGateway:      false,
				},

				// Set up an UpstreamCluster with a CredentialName when secret doesn't even exist in istio-system ns.
				// Secret fetching error at Gateway, results in a 503 response.
				{
					name:            "missing",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(credNameMissing, "-cacert"),
					useGateway:      false,
				},
				{
					name:            "no client certs",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(simpleCredName, "-cacert"),
					useGateway:      false,
				},
			}

			newTLSGateway(t, t, apps.Ns1.Namespace, apps.External.All)
			for _, tc := range testCases {
				t.NewSubTest(tc.name).Run(func(t framework.TestContext) {
					newTLSGatewayDestinationRule(t, apps.External.All, "MUTUAL", tc.credentialToUse)
					newTLSGatewayTest(t).
						Run(func(t framework.TestContext, from echo.Instance, to echo.Target) {
							callOpt := newTLSGatewayCallOpts(to, host, tc.statusCode, tc.useGateway)
							from.CallOrFail(t, callOpt)
						})
				})
			}
		})
}

// We want to test out TLS origination at Gateway, to do so traffic from client in client namespace is first
// routed to egress-gateway service in istio-system namespace and then from egress-gateway to server in server namespace.
// TLS origination at Gateway happens using DestinationRule with CredentialName reading k8s secret at the gateway proxy.
func newTLSGateway(t test.Failer, ctx resource.Context, clientNamespace namespace.Instance, to echo.Instances) {
	args := map[string]any{"to": to}

	gateway := `
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: istio-egressgateway-sds
spec:
  selector:
    istio: egressgateway
  servers:
    - port:
        number: 443
        name: https-sds
        protocol: HTTPS
      hosts:
      - {{ .to.Config.ClusterLocalFQDN }}
      tls:
        mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: egressgateway-for-server-sds
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: server
    trafficPolicy:
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: ISTIO_MUTUAL
          sni: {{ .to.Config.ClusterLocalFQDN }}
`
	vs := `
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: route-via-egressgateway-sds
spec:
  hosts:
    - {{ .to.Config.ClusterLocalFQDN }}
  gateways:
    - istio-egressgateway-sds
    - mesh
  http:
    - match:
        - gateways:
            - mesh # from sidecars, route to egress gateway service
          port: 80
      route:
        - destination:
            host: istio-egressgateway.istio-system.svc.cluster.local
            subset: server
            port:
              number: 443
          weight: 100
    - match:
        - gateways:
            - istio-egressgateway-sds
          port: 443
      route:
        - destination:
            host: {{ .to.Config.ClusterLocalFQDN }}
            port:
              number: 443
          weight: 100
      headers:
        request:
          add:
            handled-by-egress-gateway: "true"
`
	ctx.ConfigIstio().Eval(clientNamespace.Name(), args, gateway, vs).ApplyOrFail(t)
}

func newTLSGatewayDestinationRule(t framework.TestContext, to echo.Instances, destinationRuleMode string, credentialName string) {
	args := map[string]any{
		"to":             to,
		"Mode":           destinationRuleMode,
		"CredentialName": credentialName,
	}

	// Get namespace for gateway pod.
	istioCfg := istio.DefaultConfigOrFail(t, t)
	systemNS := namespace.ClaimOrFail(t, t, istioCfg.SystemNamespace)

	dr := `
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: originate-tls-for-server-sds-{{.CredentialName}}
spec:
  host: "{{ .to.Config.ClusterLocalFQDN }}"
  trafficPolicy:
    portLevelSettings:
      - port:
          number: 443
        tls:
          mode: {{.Mode}}
          credentialName: {{.CredentialName}}
          sni: {{ .to.Config.ClusterLocalFQDN }}
`

	t.ConfigKube(t.Clusters().Default()).Eval(systemNS.Name(), args, dr).
		ApplyOrFail(t)
}

func newTLSGatewayCallOpts(to echo.Target, host string, statusCode int, useGateway bool) echo.CallOptions {
	return echo.CallOptions{
		To: to,
		Port: echo.Port{
			Name: "http",
		},
		HTTP: echo.HTTP{
			Headers: headers.New().WithHost(host).Build(),
		},
		Check: check.And(
			check.NoErrorAndStatus(statusCode),
			check.Each(func(r echoClient.Response) error {
				if _, f := r.RequestHeaders["Handled-By-Egress-Gateway"]; useGateway && !f {
					return fmt.Errorf("expected to be handled by gateway. response: %s", r)
				}
				return nil
			})),
	}
}

func newTLSGatewayTest(t framework.TestContext) *echotest.T {
	return echotest.New(t, apps.All.Instances()).
		WithDefaultFilters(1, 1).
		FromMatch(match.And(
			match.Namespace(apps.Ns1.Namespace),
			match.NotNaked,
			match.NotProxylessGRPC)).
		ToMatch(match.ServiceName(apps.External.All.NamespacedName()))
}
<commit_msg>Remove unused secret creation step in egress gateway tls test (#41463)<commit_after>//go:build integ
// +build integ

// Copyright Istio 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 security

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

	"istio.io/istio/pkg/http/headers"
	"istio.io/istio/pkg/test"
	echoClient "istio.io/istio/pkg/test/echo"
	"istio.io/istio/pkg/test/env"
	"istio.io/istio/pkg/test/framework"
	"istio.io/istio/pkg/test/framework/components/echo"
	"istio.io/istio/pkg/test/framework/components/echo/check"
	"istio.io/istio/pkg/test/framework/components/echo/echotest"
	"istio.io/istio/pkg/test/framework/components/echo/match"
	"istio.io/istio/pkg/test/framework/components/istio"
	"istio.io/istio/pkg/test/framework/components/namespace"
	"istio.io/istio/pkg/test/framework/resource"
	"istio.io/istio/pkg/test/util/file"
	ingressutil "istio.io/istio/tests/integration/security/sds_ingress/util"
	sdstlsutil "istio.io/istio/tests/integration/security/sds_tls_origination/util"
)

// TestSimpleTlsOrigination test SIMPLE TLS mode with TLS origination happening at Gateway proxy
// It uses CredentialName set in DestinationRule API to fetch secrets from k8s API server
func TestSimpleTlsOrigination(t *testing.T) {
	// nolint: staticcheck
	framework.NewTest(t).
		RequiresSingleNetwork(). // https://github.com/istio/istio/issues/37134
		Features("security.egress.tls.sds").
		Run(func(t framework.TestContext) {
			var (
				credName        = "tls-credential-cacert"
				fakeCredName    = "fake-tls-credential-cacert"
				credNameMissing = "tls-credential-not-created-cacert"
			)

			credentialA := ingressutil.IngressCredential{
				CaCert: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}
			CredentialB := ingressutil.IngressCredential{
				CaCert: sdstlsutil.FakeRoot,
			}
			// Add kubernetes secret to provision key/cert for gateway.
			ingressutil.CreateIngressKubeSecret(t, credName, ingressutil.TLS, credentialA, false)

			// Add kubernetes secret to provision key/cert for gateway.
			ingressutil.CreateIngressKubeSecret(t, fakeCredName, ingressutil.TLS, CredentialB, false)

			// Set up Host Namespace
			host := apps.External.All.Config().ClusterLocalFQDN()

			testCases := []struct {
				name            string
				statusCode      int
				credentialToUse string
				useGateway      bool
			}{
				// Use CA certificate stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance.
				{
					name:            "simple",
					statusCode:      http.StatusOK,
					credentialToUse: strings.TrimSuffix(credName, "-cacert"),
					useGateway:      true,
				},
				// Use CA certificate stored as k8s secret with different issuing CA as server's CA.
				// This root certificate cannot validate the server cert presented by the echoboot server instance.
				{
					name:            "fake root",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(fakeCredName, "-cacert"),
					useGateway:      false,
				},

				// Set up an UpstreamCluster with a CredentialName when secret doesn't even exist in istio-system ns.
				// Secret fetching error at Gateway, results in a 503 response.
				{
					name:            "missing secret",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(credNameMissing, "-cacert"),
					useGateway:      false,
				},
			}

			newTLSGateway(t, t, apps.Ns1.Namespace, apps.External.All)
			for _, tc := range testCases {
				t.NewSubTest(tc.name).Run(func(t framework.TestContext) {
					newTLSGatewayDestinationRule(t, apps.External.All, "SIMPLE", tc.credentialToUse)
					newTLSGatewayTest(t).
						Run(func(t framework.TestContext, from echo.Instance, to echo.Target) {
							callOpt := newTLSGatewayCallOpts(to, host, tc.statusCode, tc.useGateway)
							from.CallOrFail(t, callOpt)
						})
				})
			}
		})
}

// TestMutualTlsOrigination test MUTUAL TLS mode with TLS origination happening at Gateway proxy
// It uses CredentialName set in DestinationRule API to fetch secrets from k8s API server
func TestMutualTlsOrigination(t *testing.T) {
	// nolint: staticcheck
	framework.NewTest(t).
		RequiresSingleNetwork(). // https://github.com/istio/istio/issues/37134
		Features("security.egress.mtls.sds").
		Run(func(t framework.TestContext) {
			var (
				credNameGeneric    = "mtls-credential-generic"
				credNameNotGeneric = "mtls-credential-not-generic"
				fakeCredNameA      = "fake-mtls-credential-a"
				credNameMissing    = "mtls-credential-not-created"
				simpleCredName     = "tls-credential-simple-cacert"
			)

			// Add kubernetes secret to provision key/cert for gateway.

			ingressutil.CreateIngressKubeSecret(t, credNameGeneric, ingressutil.Mtls, ingressutil.IngressCredential{
				Certificate: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/cert-chain.pem")),
				PrivateKey:  file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/key.pem")),
				CaCert:      file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, false)

			ingressutil.CreateIngressKubeSecret(t, credNameNotGeneric, ingressutil.Mtls, ingressutil.IngressCredential{
				Certificate: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/cert-chain.pem")),
				PrivateKey:  file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/key.pem")),
				CaCert:      file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, true)

			// Configured with an invalid ClientCert
			ingressutil.CreateIngressKubeSecret(t, fakeCredNameA, ingressutil.Mtls, ingressutil.IngressCredential{
				Certificate: sdstlsutil.FakeCert,
				PrivateKey:  file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/key.pem")),
				CaCert:      file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, false)

			ingressutil.CreateIngressKubeSecret(t, simpleCredName, ingressutil.TLS, ingressutil.IngressCredential{
				CaCert: file.AsStringOrFail(t, path.Join(env.IstioSrc, "tests/testdata/certs/dns/root-cert.pem")),
			}, false)

			// Set up Host Namespace
			host := apps.External.All.Config().ClusterLocalFQDN()

			testCases := []struct {
				name            string
				statusCode      int
				credentialToUse string
				useGateway      bool
			}{
				// Use CA certificate and client certs stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance and server CA can
				// validate the client cert. Secret is of type generic.
				{
					name:            "generic",
					statusCode:      http.StatusOK,
					credentialToUse: strings.TrimSuffix(credNameGeneric, "-cacert"),
					useGateway:      true,
				},
				// Use CA certificate and client certs stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance and server CA can
				// validate the client cert. Secret is not of type generic.
				{
					name:            "non-generic",
					statusCode:      http.StatusOK,
					credentialToUse: strings.TrimSuffix(credNameNotGeneric, "-cacert"),
					useGateway:      true,
				},
				// Use CA certificate and client certs stored as k8s secret with the same issuing CA as server's CA.
				// This root certificate can validate the server cert presented by the echoboot server instance and server CA
				// cannot validate the client cert. Returns 503 response as TLS handshake fails.
				{
					name:            "invalid client cert",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(fakeCredNameA, "-cacert"),
					useGateway:      false,
				},

				// Set up an UpstreamCluster with a CredentialName when secret doesn't even exist in istio-system ns.
				// Secret fetching error at Gateway, results in a 503 response.
				{
					name:            "missing",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(credNameMissing, "-cacert"),
					useGateway:      false,
				},
				{
					name:            "no client certs",
					statusCode:      http.StatusServiceUnavailable,
					credentialToUse: strings.TrimSuffix(simpleCredName, "-cacert"),
					useGateway:      false,
				},
			}

			newTLSGateway(t, t, apps.Ns1.Namespace, apps.External.All)
			for _, tc := range testCases {
				t.NewSubTest(tc.name).Run(func(t framework.TestContext) {
					newTLSGatewayDestinationRule(t, apps.External.All, "MUTUAL", tc.credentialToUse)
					newTLSGatewayTest(t).
						Run(func(t framework.TestContext, from echo.Instance, to echo.Target) {
							callOpt := newTLSGatewayCallOpts(to, host, tc.statusCode, tc.useGateway)
							from.CallOrFail(t, callOpt)
						})
				})
			}
		})
}

// We want to test out TLS origination at Gateway, to do so traffic from client in client namespace is first
// routed to egress-gateway service in istio-system namespace and then from egress-gateway to server in server namespace.
// TLS origination at Gateway happens using DestinationRule with CredentialName reading k8s secret at the gateway proxy.
func newTLSGateway(t test.Failer, ctx resource.Context, clientNamespace namespace.Instance, to echo.Instances) {
	args := map[string]any{"to": to}

	gateway := `
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: istio-egressgateway-sds
spec:
  selector:
    istio: egressgateway
  servers:
    - port:
        number: 443
        name: https-sds
        protocol: HTTPS
      hosts:
      - {{ .to.Config.ClusterLocalFQDN }}
      tls:
        mode: ISTIO_MUTUAL
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: egressgateway-for-server-sds
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: server
    trafficPolicy:
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: ISTIO_MUTUAL
          sni: {{ .to.Config.ClusterLocalFQDN }}
`
	vs := `
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: route-via-egressgateway-sds
spec:
  hosts:
    - {{ .to.Config.ClusterLocalFQDN }}
  gateways:
    - istio-egressgateway-sds
    - mesh
  http:
    - match:
        - gateways:
            - mesh # from sidecars, route to egress gateway service
          port: 80
      route:
        - destination:
            host: istio-egressgateway.istio-system.svc.cluster.local
            subset: server
            port:
              number: 443
          weight: 100
    - match:
        - gateways:
            - istio-egressgateway-sds
          port: 443
      route:
        - destination:
            host: {{ .to.Config.ClusterLocalFQDN }}
            port:
              number: 443
          weight: 100
      headers:
        request:
          add:
            handled-by-egress-gateway: "true"
`
	ctx.ConfigIstio().Eval(clientNamespace.Name(), args, gateway, vs).ApplyOrFail(t)
}

func newTLSGatewayDestinationRule(t framework.TestContext, to echo.Instances, destinationRuleMode string, credentialName string) {
	args := map[string]any{
		"to":             to,
		"Mode":           destinationRuleMode,
		"CredentialName": credentialName,
	}

	// Get namespace for gateway pod.
	istioCfg := istio.DefaultConfigOrFail(t, t)
	systemNS := namespace.ClaimOrFail(t, t, istioCfg.SystemNamespace)

	dr := `
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: originate-tls-for-server-sds-{{.CredentialName}}
spec:
  host: "{{ .to.Config.ClusterLocalFQDN }}"
  trafficPolicy:
    portLevelSettings:
      - port:
          number: 443
        tls:
          mode: {{.Mode}}
          credentialName: {{.CredentialName}}
          sni: {{ .to.Config.ClusterLocalFQDN }}
`

	t.ConfigKube(t.Clusters().Default()).Eval(systemNS.Name(), args, dr).
		ApplyOrFail(t)
}

func newTLSGatewayCallOpts(to echo.Target, host string, statusCode int, useGateway bool) echo.CallOptions {
	return echo.CallOptions{
		To: to,
		Port: echo.Port{
			Name: "http",
		},
		HTTP: echo.HTTP{
			Headers: headers.New().WithHost(host).Build(),
		},
		Check: check.And(
			check.NoErrorAndStatus(statusCode),
			check.Each(func(r echoClient.Response) error {
				if _, f := r.RequestHeaders["Handled-By-Egress-Gateway"]; useGateway && !f {
					return fmt.Errorf("expected to be handled by gateway. response: %s", r)
				}
				return nil
			})),
	}
}

func newTLSGatewayTest(t framework.TestContext) *echotest.T {
	return echotest.New(t, apps.All.Instances()).
		WithDefaultFilters(1, 1).
		FromMatch(match.And(
			match.Namespace(apps.Ns1.Namespace),
			match.NotNaked,
			match.NotProxylessGRPC)).
		ToMatch(match.ServiceName(apps.External.All.NamespacedName()))
}
<|endoftext|>


<commit_before>package trollmode

import (
	"math"
	"math/rand"
	"socialapi/models"
	"socialapi/rest"
	"socialapi/workers/common/runner"
	"socialapi/workers/common/tests"
	"strconv"
	"testing"
	"time"

	"github.com/koding/bongo"
	. "github.com/smartystreets/goconvey/convey"
	"labix.org/v2/mgo/bson"
)

func TestMarkedAsTroll(t *testing.T) {
	r := runner.New("TrollMode-Test")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()
	// disable logs
	// r.Log.SetLevel(logging.CRITICAL)

	Convey("given a controller", t, func() {

		// cretae admin user
		adminUser := models.NewAccount()
		adminUser.OldId = bson.NewObjectId().Hex()
		adminUser, err = rest.CreateAccount(adminUser)
		tests.ResultedWithNoErrorCheck(adminUser, err)

		// create troll user
		trollUser := models.NewAccount()
		trollUser.OldId = bson.NewObjectId().Hex()
		trollUser, err := rest.CreateAccount(trollUser)
		tests.ResultedWithNoErrorCheck(trollUser, err)
		trollUser.IsTroll = true

		// create normal user
		normalUser := models.NewAccount()
		normalUser.OldId = bson.NewObjectId().Hex()
		normalUser, err = rest.CreateAccount(normalUser)
		tests.ResultedWithNoErrorCheck(normalUser, err)

		// create groupName
		rand.Seed(time.Now().UnixNano())
		groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)
		groupChannel, err := rest.CreateChannelByGroupNameAndType(
			adminUser.Id,
			groupName,
			models.Channel_TYPE_GROUP,
		)

		controller := NewController(r.Log)

		Convey("err should be nil", func() {
			So(err, ShouldBeNil)
		})

		Convey("controller should be set", func() {
			So(controller, ShouldNotBeNil)
		})

		Convey("should return nil when given nil account", func() {
			So(controller.MarkedAsTroll(nil), ShouldBeNil)
		})

		Convey("should return nil when account id given 0", func() {
			So(controller.MarkedAsTroll(models.NewAccount()), ShouldBeNil)
		})

		Convey("non existing account should not give error", func() {
			a := models.NewAccount()
			a.Id = math.MaxInt64
			So(controller.MarkedAsTroll(a), ShouldBeNil)
		})

		Convey("non existing account should not give error", func() {
			a := models.NewAccount()
			a.Id = math.MaxInt64
			So(controller.MarkedAsTroll(a), ShouldBeNil)
		})

		/////////////////////////  marking all content ////////////////////////
		// mark channel
		Convey("private channels of a troll should be marked as exempt", func() {
			// fetch from api, because we need to test system from there
			privatemessageChannelId1, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId1, ShouldBeGreaterThan, 0)

			privatemessageChannelId2, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId2, ShouldBeGreaterThan, 0)

			So(controller.markChannels(trollUser), ShouldBeNil)

			// fetch channel from db
			c1 := models.NewChannel()
			err = c1.ById(privatemessageChannelId1)
			So(err, ShouldBeNil)
			So(c1.Id, ShouldEqual, privatemessageChannelId1)
			// check here
			So(c1.MetaBits.IsTroll(), ShouldBeTrue)

			// fetch channel from db
			c2 := models.NewChannel()
			err = c2.ById(privatemessageChannelId2)
			So(err, ShouldBeNil)
			So(c2.Id, ShouldEqual, privatemessageChannelId2)

			// check here
			So(c2.MetaBits.IsTroll(), ShouldBeTrue)
		})

		// mark channel
		Convey("public channels of a troll should not be marked as exempt", nil)

		// mark channel_participant
		Convey("participations of a troll should not be marked as exempt", func() {
			// fetch from api, because we need to test system from there
			privatemessageChannelId1, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId1, ShouldBeGreaterThan, 0)

			privatemessageChannelId2, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId2, ShouldBeGreaterThan, 0)

			So(controller.markParticipations(trollUser), ShouldBeNil)

			var participations []models.ChannelParticipant

			query := &bongo.Query{
				Selector: map[string]interface{}{
					"account_id": trollUser.Id,
				},
			}

			err = models.NewChannelParticipant().Some(&participations, query)
			So(err, ShouldBeNil)
			for _, participation := range participations {
				So(participation.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// mark channel_message_list
		Convey("massages that are in all channels that are created by troll, should be marked as exempt", func() {
			// post, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			// tests.ResultedWithNoErrorCheck(post, err)

			// post, err = rest.CreatePost(groupChannel.Id, trollUser.Id)
			// tests.ResultedWithNoErrorCheck(post, err)
		})

		// mark channel_message
		Convey("messages of a troll should be marked as exempt", func() {
			post1, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post1, err)

			post2, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post2, err)

			So(controller.markMessages(trollUser), ShouldBeNil)

			cm := models.NewChannelMessage()
			q := &bongo.Query{
				Selector: map[string]interface{}{
					"account_id": trollUser.Id,
				},
			}

			var messages []models.ChannelMessage
			err = cm.Some(&messages, q)
			So(err, ShouldBeNil)

			for _, message := range messages {
				So(message.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// mark interactions
		Convey("interactions of a troll should be marked as exempt", func() {
			post1, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post1, err)

			err = rest.AddInteraction("like", post1.Id, trollUser.Id)
			So(err, ShouldBeNil)

			So(controller.markInteractions(trollUser), ShouldBeNil)

			cm := models.NewInteraction()
			q := &bongo.Query{
				Selector: map[string]interface{}{
					"account_id": trollUser.Id,
				},
			}

			var interactions []models.Interaction
			err = cm.Some(&interactions, q)
			So(err, ShouldBeNil)

			for _, interaction := range interactions {
				So(interaction.MetaBits.IsTroll(), ShouldBeTrue)
				So(interaction.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// mark message_reply
		Convey("replies of a troll should be marked as exempt", func() {
			// create post
			post, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post, err)

			// create reply
			reply, err := rest.AddReply(post.Id, post.AccountId, groupChannel.Id)
			So(err, ShouldBeNil)
			So(reply, ShouldNotBeNil)
			So(reply.AccountId, ShouldEqual, post.AccountId)

			So(controller.markMessageRepliesAsExempt(reply), ShouldBeNil)

			mr := models.NewMessageReply()
			q := &bongo.Query{
				Selector: map[string]interface{}{
					"reply_id": reply.Id,
				},
			}

			var mrs []models.MessageReply
			err = mr.Some(&mrs, q)
			So(err, ShouldBeNil)

			So(len(mrs), ShouldBeGreaterThan, 0)

			for _, mr := range mrs {
				So(mr.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// update channel data while creating
		Convey("when a troll creates a channel, meta_bits should be set", func() {
			privatemessageChannelId1, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId1, ShouldBeGreaterThan, 0)

			// fetch channel from db
			c1 := models.NewChannel()
			err = c1.ById(privatemessageChannelId1)
			So(err, ShouldBeNil)
			So(c1.Id, ShouldEqual, privatemessageChannelId1)

			So(c1.MetaBits.IsTroll(), ShouldBeTrue)
		})

		// update channel_participant data while creating
		Convey("when a troll is added to a channel as participant, meta_bits should be set", func() {
			privatemessageChannelId, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId, ShouldBeGreaterThan, 0)

			// fetch channel from db
			cp := models.NewChannelParticipant()
			cp.AccountId = trollUser.Id
			cp.ChannelId = privatemessageChannelId

			So(cp.FetchParticipant(), ShouldBeNil)
			So(cp.AccountId, ShouldEqual, trollUser.Id)

			So(cp.MetaBits.IsTroll(), ShouldBeTrue)
		})

		// update channel_message_list data while creating
		Convey("when a troll content is added to a channel, meta_bits should be set", func() {
			privatemessageChannelId, err := createPrivateMessageChannel(normalUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId, ShouldBeGreaterThan, 0)

			// add a message from a troll user
			post, err := rest.CreatePost(privatemessageChannelId, trollUser.Id)
			So(err, ShouldBeNil)
			So(post, ShouldNotBeNil)

			// fetch last message
			c := models.NewChannel()
			c.Id = privatemessageChannelId
			ml, err := c.FetchMessageList(post.Id)
			tests.ResultedWithNoErrorCheck(ml, err)

			So(ml.MetaBits.IsTroll(), ShouldBeTrue)

		})
	})
}

func createPrivateMessageChannel(accountId int64, groupName string) (int64, error) {
	// create first private channel
	cmc, err := rest.SendPrivateMessage(
		accountId,
		"this is a body for private message @sinan",
		groupName,
	)
	if err != nil {
		return 0, err
	}

	return cmc.Channel.Id, nil
}
<commit_msg>social: troll: test updating channel_message data while creating<commit_after>package trollmode

import (
	"math"
	"math/rand"
	"socialapi/models"
	"socialapi/rest"
	"socialapi/workers/common/runner"
	"socialapi/workers/common/tests"
	"strconv"
	"testing"
	"time"

	"github.com/koding/bongo"
	. "github.com/smartystreets/goconvey/convey"
	"labix.org/v2/mgo/bson"
)

func TestMarkedAsTroll(t *testing.T) {
	r := runner.New("TrollMode-Test")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()
	// disable logs
	// r.Log.SetLevel(logging.CRITICAL)

	Convey("given a controller", t, func() {

		// cretae admin user
		adminUser := models.NewAccount()
		adminUser.OldId = bson.NewObjectId().Hex()
		adminUser, err = rest.CreateAccount(adminUser)
		tests.ResultedWithNoErrorCheck(adminUser, err)

		// create troll user
		trollUser := models.NewAccount()
		trollUser.OldId = bson.NewObjectId().Hex()
		trollUser, err := rest.CreateAccount(trollUser)
		tests.ResultedWithNoErrorCheck(trollUser, err)
		trollUser.IsTroll = true

		// create normal user
		normalUser := models.NewAccount()
		normalUser.OldId = bson.NewObjectId().Hex()
		normalUser, err = rest.CreateAccount(normalUser)
		tests.ResultedWithNoErrorCheck(normalUser, err)

		// create groupName
		rand.Seed(time.Now().UnixNano())
		groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)
		groupChannel, err := rest.CreateChannelByGroupNameAndType(
			adminUser.Id,
			groupName,
			models.Channel_TYPE_GROUP,
		)

		controller := NewController(r.Log)

		Convey("err should be nil", func() {
			So(err, ShouldBeNil)
		})

		Convey("controller should be set", func() {
			So(controller, ShouldNotBeNil)
		})

		Convey("should return nil when given nil account", func() {
			So(controller.MarkedAsTroll(nil), ShouldBeNil)
		})

		Convey("should return nil when account id given 0", func() {
			So(controller.MarkedAsTroll(models.NewAccount()), ShouldBeNil)
		})

		Convey("non existing account should not give error", func() {
			a := models.NewAccount()
			a.Id = math.MaxInt64
			So(controller.MarkedAsTroll(a), ShouldBeNil)
		})

		Convey("non existing account should not give error", func() {
			a := models.NewAccount()
			a.Id = math.MaxInt64
			So(controller.MarkedAsTroll(a), ShouldBeNil)
		})

		/////////////////////////  marking all content ////////////////////////
		// mark channel
		Convey("private channels of a troll should be marked as exempt", func() {
			// fetch from api, because we need to test system from there
			privatemessageChannelId1, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId1, ShouldBeGreaterThan, 0)

			privatemessageChannelId2, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId2, ShouldBeGreaterThan, 0)

			So(controller.markChannels(trollUser), ShouldBeNil)

			// fetch channel from db
			c1 := models.NewChannel()
			err = c1.ById(privatemessageChannelId1)
			So(err, ShouldBeNil)
			So(c1.Id, ShouldEqual, privatemessageChannelId1)
			// check here
			So(c1.MetaBits.IsTroll(), ShouldBeTrue)

			// fetch channel from db
			c2 := models.NewChannel()
			err = c2.ById(privatemessageChannelId2)
			So(err, ShouldBeNil)
			So(c2.Id, ShouldEqual, privatemessageChannelId2)

			// check here
			So(c2.MetaBits.IsTroll(), ShouldBeTrue)
		})

		// mark channel
		Convey("public channels of a troll should not be marked as exempt", nil)

		// mark channel_participant
		Convey("participations of a troll should not be marked as exempt", func() {
			// fetch from api, because we need to test system from there
			privatemessageChannelId1, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId1, ShouldBeGreaterThan, 0)

			privatemessageChannelId2, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId2, ShouldBeGreaterThan, 0)

			So(controller.markParticipations(trollUser), ShouldBeNil)

			var participations []models.ChannelParticipant

			query := &bongo.Query{
				Selector: map[string]interface{}{
					"account_id": trollUser.Id,
				},
			}

			err = models.NewChannelParticipant().Some(&participations, query)
			So(err, ShouldBeNil)
			for _, participation := range participations {
				So(participation.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// mark channel_message_list
		Convey("massages that are in all channels that are created by troll, should be marked as exempt", func() {
			// post, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			// tests.ResultedWithNoErrorCheck(post, err)

			// post, err = rest.CreatePost(groupChannel.Id, trollUser.Id)
			// tests.ResultedWithNoErrorCheck(post, err)
		})

		// mark channel_message
		Convey("messages of a troll should be marked as exempt", func() {
			post1, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post1, err)

			post2, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post2, err)

			So(controller.markMessages(trollUser), ShouldBeNil)

			cm := models.NewChannelMessage()
			q := &bongo.Query{
				Selector: map[string]interface{}{
					"account_id": trollUser.Id,
				},
			}

			var messages []models.ChannelMessage
			err = cm.Some(&messages, q)
			So(err, ShouldBeNil)

			for _, message := range messages {
				So(message.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// mark interactions
		Convey("interactions of a troll should be marked as exempt", func() {
			post1, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post1, err)

			err = rest.AddInteraction("like", post1.Id, trollUser.Id)
			So(err, ShouldBeNil)

			So(controller.markInteractions(trollUser), ShouldBeNil)

			cm := models.NewInteraction()
			q := &bongo.Query{
				Selector: map[string]interface{}{
					"account_id": trollUser.Id,
				},
			}

			var interactions []models.Interaction
			err = cm.Some(&interactions, q)
			So(err, ShouldBeNil)

			for _, interaction := range interactions {
				So(interaction.MetaBits.IsTroll(), ShouldBeTrue)
				So(interaction.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// mark message_reply
		Convey("replies of a troll should be marked as exempt", func() {
			// create post
			post, err := rest.CreatePost(groupChannel.Id, trollUser.Id)
			tests.ResultedWithNoErrorCheck(post, err)

			// create reply
			reply, err := rest.AddReply(post.Id, post.AccountId, groupChannel.Id)
			So(err, ShouldBeNil)
			So(reply, ShouldNotBeNil)
			So(reply.AccountId, ShouldEqual, post.AccountId)

			So(controller.markMessageRepliesAsExempt(reply), ShouldBeNil)

			mr := models.NewMessageReply()
			q := &bongo.Query{
				Selector: map[string]interface{}{
					"reply_id": reply.Id,
				},
			}

			var mrs []models.MessageReply
			err = mr.Some(&mrs, q)
			So(err, ShouldBeNil)

			So(len(mrs), ShouldBeGreaterThan, 0)

			for _, mr := range mrs {
				So(mr.MetaBits.IsTroll(), ShouldBeTrue)
			}
		})

		// update channel data while creating
		Convey("when a troll creates a channel, meta_bits should be set", func() {
			privatemessageChannelId1, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId1, ShouldBeGreaterThan, 0)

			// fetch channel from db
			c1 := models.NewChannel()
			err = c1.ById(privatemessageChannelId1)
			So(err, ShouldBeNil)
			So(c1.Id, ShouldEqual, privatemessageChannelId1)

			So(c1.MetaBits.IsTroll(), ShouldBeTrue)
		})

		// update channel_participant data while creating
		Convey("when a troll is added to a channel as participant, meta_bits should be set", func() {
			privatemessageChannelId, err := createPrivateMessageChannel(trollUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId, ShouldBeGreaterThan, 0)

			// fetch channel from db
			cp := models.NewChannelParticipant()
			cp.AccountId = trollUser.Id
			cp.ChannelId = privatemessageChannelId

			So(cp.FetchParticipant(), ShouldBeNil)
			So(cp.AccountId, ShouldEqual, trollUser.Id)

			So(cp.MetaBits.IsTroll(), ShouldBeTrue)
		})

		// update channel_message_list data while creating
		Convey("when a troll content is added to a channel, meta_bits should be set", func() {
			privatemessageChannelId, err := createPrivateMessageChannel(normalUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId, ShouldBeGreaterThan, 0)

			// add a message from a troll user
			post, err := rest.CreatePost(privatemessageChannelId, trollUser.Id)
			So(err, ShouldBeNil)
			So(post, ShouldNotBeNil)

			// fetch last message
			c := models.NewChannel()
			c.Id = privatemessageChannelId
			ml, err := c.FetchMessageList(post.Id)
			tests.ResultedWithNoErrorCheck(ml, err)

			So(ml.MetaBits.IsTroll(), ShouldBeTrue)

		})

		// update channel_message data while creating
		Convey("when a troll posts a status update, meta_bits should be set", func() {
			privatemessageChannelId, err := createPrivateMessageChannel(normalUser.Id, groupName)
			So(err, ShouldBeNil)
			So(privatemessageChannelId, ShouldBeGreaterThan, 0)

			// add a message from a troll user
			post, err := rest.CreatePost(privatemessageChannelId, trollUser.Id)
			So(err, ShouldBeNil)
			So(post, ShouldNotBeNil)

			// fetch last message
			c := models.NewChannel()
			c.Id = privatemessageChannelId
			lastMessage, err := c.FetchLastMessage()
			tests.ResultedWithNoErrorCheck(lastMessage, err)

			So(lastMessage.MetaBits.IsTroll(), ShouldBeTrue)

		})

	})
}

func createPrivateMessageChannel(accountId int64, groupName string) (int64, error) {
	// create first private channel
	cmc, err := rest.SendPrivateMessage(
		accountId,
		"this is a body for private message @sinan",
		groupName,
	)
	if err != nil {
		return 0, err
	}

	return cmc.Channel.Id, nil
}
<|endoftext|>


<commit_before>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build windows

package winfsnotify

import (
	"os"
	"testing"
	"time"
)

func expect(t *testing.T, eventstream <-chan *Event, name string, mask uint32) {
	t.Logf(`expected: "%s": 0x%x`, name, mask)
	select {
	case event := <-eventstream:
		if event == nil {
			t.Fatal("nil event received")
		}
		t.Logf("received: %s", event)
		if event.Name != name || event.Mask != mask {
			t.Fatal("did not receive expected event")
		}
	case <-time.After(1 * time.Second):
		t.Fatal("timed out waiting for event")
	}
}

func TestNotifyEvents(t *testing.T) {
	watcher, err := NewWatcher()
	if err != nil {
		t.Fatalf("NewWatcher() failed: %s", err)
	}

	testDir := "TestNotifyEvents.testdirectory"
	testFile := testDir + "/TestNotifyEvents.testfile"
	testFile2 := testFile + ".new"
	const mask = FS_ALL_EVENTS & ^(FS_ATTRIB|FS_CLOSE) | FS_IGNORED

	// Add a watch for testDir
	os.RemoveAll(testDir)
	if err = os.Mkdir(testDir, 0777); err != nil {
		t.Fatalf("Failed to create test directory: %s", err)
	}
	defer os.RemoveAll(testDir)
	err = watcher.AddWatch(testDir, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	// Receive errors on the error channel on a separate goroutine
	go func() {
		for err := range watcher.Error {
			t.Fatalf("error received: %s", err)
		}
	}()

	// Create a file
	file, err := os.Create(testFile)
	if err != nil {
		t.Fatalf("creating test file failed: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_CREATE)

	err = watcher.AddWatch(testFile, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	if _, err = file.WriteString("hello, world"); err != nil {
		t.Fatalf("failed to write to test file: %s", err)
	}
	if err = file.Close(); err != nil {
		t.Fatalf("failed to close test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MODIFY)
	expect(t, watcher.Event, testFile, FS_MODIFY)

	if err = os.Rename(testFile, testFile2); err != nil {
		t.Fatalf("failed to rename test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MOVED_FROM)
	expect(t, watcher.Event, testFile2, FS_MOVED_TO)
	expect(t, watcher.Event, testFile, FS_MOVE_SELF)

	if err = os.RemoveAll(testDir); err != nil {
		t.Fatalf("failed to remove test directory: %s", err)
	}
	expect(t, watcher.Event, testFile2, FS_DELETE_SELF)
	expect(t, watcher.Event, testFile2, FS_IGNORED)
	expect(t, watcher.Event, testFile2, FS_DELETE)
	expect(t, watcher.Event, testDir, FS_DELETE_SELF)
	expect(t, watcher.Event, testDir, FS_IGNORED)

	t.Log("calling Close()")
	if err = watcher.Close(); err != nil {
		t.Fatalf("failed to close watcher: %s", err)
	}
}

func TestNotifyClose(t *testing.T) {
	watcher, _ := NewWatcher()
	watcher.Close()

	done := false
	go func() {
		watcher.Close()
		done = true
	}()

	time.Sleep(50 * time.Millisecond)
	if !done {
		t.Fatal("double Close() test failed: second Close() call didn't return")
	}

	dir, err := ioutil.TempDir("", "wininotify")
	if err != nil {
		t.Fatalf("TempDir failed: %s", err)
	}
	defer os.RemoveAll(dir)

	err = watcher.Watch(dir)
	if err == nil {
		t.Fatal("expected error on Watch() after Close(), got nil")
	}
}
<commit_msg>windows: fix build<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build windows

package winfsnotify

import (
	"io/ioutil"
	"os"
	"testing"
	"time"
)

func expect(t *testing.T, eventstream <-chan *Event, name string, mask uint32) {
	t.Logf(`expected: "%s": 0x%x`, name, mask)
	select {
	case event := <-eventstream:
		if event == nil {
			t.Fatal("nil event received")
		}
		t.Logf("received: %s", event)
		if event.Name != name || event.Mask != mask {
			t.Fatal("did not receive expected event")
		}
	case <-time.After(1 * time.Second):
		t.Fatal("timed out waiting for event")
	}
}

func TestNotifyEvents(t *testing.T) {
	watcher, err := NewWatcher()
	if err != nil {
		t.Fatalf("NewWatcher() failed: %s", err)
	}

	testDir := "TestNotifyEvents.testdirectory"
	testFile := testDir + "/TestNotifyEvents.testfile"
	testFile2 := testFile + ".new"
	const mask = FS_ALL_EVENTS & ^(FS_ATTRIB|FS_CLOSE) | FS_IGNORED

	// Add a watch for testDir
	os.RemoveAll(testDir)
	if err = os.Mkdir(testDir, 0777); err != nil {
		t.Fatalf("Failed to create test directory: %s", err)
	}
	defer os.RemoveAll(testDir)
	err = watcher.AddWatch(testDir, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	// Receive errors on the error channel on a separate goroutine
	go func() {
		for err := range watcher.Error {
			t.Fatalf("error received: %s", err)
		}
	}()

	// Create a file
	file, err := os.Create(testFile)
	if err != nil {
		t.Fatalf("creating test file failed: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_CREATE)

	err = watcher.AddWatch(testFile, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	if _, err = file.WriteString("hello, world"); err != nil {
		t.Fatalf("failed to write to test file: %s", err)
	}
	if err = file.Close(); err != nil {
		t.Fatalf("failed to close test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MODIFY)
	expect(t, watcher.Event, testFile, FS_MODIFY)

	if err = os.Rename(testFile, testFile2); err != nil {
		t.Fatalf("failed to rename test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MOVED_FROM)
	expect(t, watcher.Event, testFile2, FS_MOVED_TO)
	expect(t, watcher.Event, testFile, FS_MOVE_SELF)

	if err = os.RemoveAll(testDir); err != nil {
		t.Fatalf("failed to remove test directory: %s", err)
	}
	expect(t, watcher.Event, testFile2, FS_DELETE_SELF)
	expect(t, watcher.Event, testFile2, FS_IGNORED)
	expect(t, watcher.Event, testFile2, FS_DELETE)
	expect(t, watcher.Event, testDir, FS_DELETE_SELF)
	expect(t, watcher.Event, testDir, FS_IGNORED)

	t.Log("calling Close()")
	if err = watcher.Close(); err != nil {
		t.Fatalf("failed to close watcher: %s", err)
	}
}

func TestNotifyClose(t *testing.T) {
	watcher, _ := NewWatcher()
	watcher.Close()

	done := false
	go func() {
		watcher.Close()
		done = true
	}()

	time.Sleep(50 * time.Millisecond)
	if !done {
		t.Fatal("double Close() test failed: second Close() call didn't return")
	}

	dir, err := ioutil.TempDir("", "wininotify")
	if err != nil {
		t.Fatalf("TempDir failed: %s", err)
	}
	defer os.RemoveAll(dir)

	err = watcher.Watch(dir)
	if err == nil {
		t.Fatal("expected error on Watch() after Close(), got nil")
	}
}
<|endoftext|>


<commit_before>package acceptance_test

import (
	"net/http"
	"testing"

	. "github.com/cloudfoundry-incubator/bits-service/acceptance_test"
	acceptance "github.com/cloudfoundry-incubator/bits-service/acceptance_test"
	"github.com/onsi/ginkgo"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	. "github.com/onsi/gomega"
)

var client = &http.Client{}

func TestEndToEnd(t *testing.T) {
	gomega.RegisterFailHandler(ginkgo.Fail)
	CreateFakeEiriniFS()

	acceptance.SetUpAndTearDownServer()
	ginkgo.RunSpecs(t, "EndToEnd Identical registry and public hostname")
}

var _ = Describe("Accessing the bits-service", func() {
	Context("when public and registry endpoint use the same hostname", func() {
		Context("accessing non-exiting package through public host", func() {
			It("gets a status forbidden from the signature verification middleware", func() {
				Expect(client.Get("http://public-and-registry.127.0.0.1.nip.io:8888/packages/notexistent")).
					To(WithTransform(GetStatusCode, Equal(http.StatusForbidden)))
			})
		})

		Context("accessing OCI /v2 endpoint through registry host", func() {
			It("gets an HTTP Status OK", func() {
				Expect(client.Get("http://public-and-registry.127.0.0.1.nip.io:8888/v2/")).
					To(WithTransform(GetStatusCode, Equal(http.StatusOK)))
			})
		})
	})
})
<commit_msg>Add acceptance test for OCI bacis auth<commit_after>package acceptance_test

import (
	"net/http"
	"testing"

	. "github.com/cloudfoundry-incubator/bits-service/acceptance_test"
	acceptance "github.com/cloudfoundry-incubator/bits-service/acceptance_test"
	"github.com/onsi/ginkgo"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	. "github.com/onsi/gomega"
)

var client = &http.Client{}

func TestEndToEnd(t *testing.T) {
	gomega.RegisterFailHandler(ginkgo.Fail)
	CreateFakeEiriniFS()

	acceptance.SetUpAndTearDownServer()
	ginkgo.RunSpecs(t, "EndToEnd Identical registry and public hostname")
}

var _ = Describe("Accessing the bits-service", func() {
	Context("when public and registry endpoint use the same hostname", func() {
		Context("accessing non-exiting package through public host", func() {
			It("gets a status forbidden from the signature verification middleware", func() {
				Expect(client.Get("http://public-and-registry.127.0.0.1.nip.io:8888/packages/notexistent")).
					To(WithTransform(GetStatusCode, Equal(http.StatusForbidden)))
			})
		})

		Context("accessing OCI /v2 endpoint through registry host", func() {
			It("gets an HTTP Status OK", func() {
				req, err := http.NewRequest("GET", "http://public-and-registry.127.0.0.1.nip.io:8888/v2/", nil)
				Expect(err).ToNot(HaveOccurred())

				req.SetBasicAuth("the-username", "the-password")
				Expect(client.Do(req)).To(WithTransform(GetStatusCode, Equal(http.StatusOK)))
			})
		})
	})
})
<|endoftext|>


<commit_before><commit_msg>Allow volume test to run outside an actual OpenStack VM<commit_after><|endoftext|>