<commit_before>package transports

import (
	"github.com/Forau/yanngo/api"
	"github.com/Forau/yanngo/httpcli"

	"encoding/json"

	"fmt"
)

func NewDefaultTransport(endpoint string, user, pass, rawPem []byte) (transp api.TransportHandler, err error) {
	restcli := httpcli.NewRestClient(endpoint, user, pass, rawPem)

	defTransp := make(api.RequestCommandTransport)
	transp = defTransp

	makeHandler := func(method, path string, pathArgs, postArgs []string) func(api.Params) (json.RawMessage, error) {
		return func(p api.Params) (json.RawMessage, error) {
			parsedPath := p.Sprintf(path, pathArgs...)
			res, err := restcli.Execute(method, parsedPath, p.SubParams(postArgs...))
			fmt.Printf("\nGot response from http: %+v\n\n", string(res))
			return res, err
		}
	}

	defTransp.AddCommand(string(api.SessionCmd)).Description("Get the current session from last login").
		Handler(makeHandler("SPECIAL", "session", []string{}, []string{}))

	defTransp.AddCommand(string(api.AccountsCmd)).Description("Get list of accounts").TTLHours(12).
		Handler(makeHandler("GET", "accounts", []string{}, []string{}))

	defTransp.AddCommand(string(api.AccountCmd)).Description("Get account info").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.AccountLedgersCmd)).Description("AccountLedgersCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/ledgers", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.AccountOrdersCmd)).Description("AccountOrdersCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/orders", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.CreateOrderCmd)).Description("CreateOrderCmd").
		AddArgument("accno").
		AddArgument("identifier").
		AddArgument("market_id").
		AddArgument("price").
		AddArgument("currency").
		AddArgument("volume").
		AddFullArgument("side", "Buy or Sell", []string{"BUY", "SELL"}, false).
		AddFullArgument("order_type", "The order type", []string{"FAK", "FOK", "LIMIT", "STOP_LIMIT", "STOP_TRAILING", "OCO"}, true).
		AddOptArgument("valid_until").
		AddOptArgument("open_volume").
		AddOptArgument("reference").
		AddFullArgument("activation_condition", "Used for stop loss orders", []string{"STOP_ACTPRICE_PERC", "STOP_ACTPRICE", "MANUAL", "OCO_STOP_ACTPRICE"}, true).
		AddOptArgument("trigger_value").
		AddFullArgument("trigger_condition", "Condition to trigger", []string{"<=", ">="}, true).
		AddOptArgument("target_value").
		Handler(makeHandler("POST", "accounts/%v/orders", []string{"accno"},
		[]string{"identifier", "market_id", "price", "currency", "volume", "side", "order_type", "valid_until", "open_volume",
			"reference", "activation_condition", "trigger_value", "trigger_condition", "target_value"}))

	defTransp.AddCommand(string(api.ActivateOrderCmd)).Description("ActivateOrderCmd").
		AddArgument("accno").AddArgument("order_id").
		Handler(makeHandler("PUT", "accounts/%v/orders/%v/activate", []string{"accno", "order_id"}, []string{}))

	defTransp.AddCommand(string(api.UpdateOrderCmd)).Description("UpdateOrderCmd").
		AddArgument("accno").AddArgument("order_id").
		AddArgument("price").
		AddArgument("currency").
		AddArgument("volume").
		Handler(makeHandler("PUT", "accounts/%v/orders/%v", []string{"accno", "order_id"},
		[]string{"price", "currency", "volume"}))

	defTransp.AddCommand(string(api.DeleteOrderCmd)).Description("DeleteOrderCmd").
		AddArgument("accno").AddArgument("order_id").
		Handler(makeHandler("DELETE", "accounts/%v/orders/%v", []string{"accno", "order_id"}, []string{}))

	defTransp.AddCommand(string(api.AccountPositionsCmd)).Description("AccountPositionsCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/positions", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.AccountTradesCmd)).Description("AccountTradesCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/trades", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.CountriesCmd)).Description("CountriesCmd").TTLHours(12).
		AddFullArgument("countries", "Countries to query. Coma separated list", []string{}, true).
		Handler(makeHandler("GET", "countries/%v", []string{"countries"}, []string{}))

	defTransp.AddCommand(string(api.IndicatorsCmd)).Description("IndicatorsCmd").TTLHours(12).
		AddFullArgument("indicators", "Indicators to query. Format: SRC:ID,...", []string{}, true).
		Handler(makeHandler("GET", "indicators/%v", []string{"indicators"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentsCmd)).Description("InstrumentsCmd").TTLHours(12).
		AddArgument("instruments").Handler(makeHandler("GET", "instruments/%v", []string{"instruments"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentSearchCmd)).Description("InstrumentSearchCmd").
		AddArgument("query").AddOptArgument("instrument_group_type").AddOptArgument("limit").AddOptArgument("offset").
		AddFullArgument("fuzzy", "", []string{"true", "false"}, true).
		Handler(makeHandler("GET", "instruments", []string{}, []string{"query", "instrument_group_type", "limit", "offset", "fuzzy"}))

	defTransp.AddCommand(string(api.InstrumentLeveragesCmd)).Description("InstrumentLeveragesCmd").
		AddArgument("instrument").
		AddOptArgument("expiration_date").AddOptArgument("issuer_id").
		AddFullArgument("market_view", "Filter on market view", []string{"U", "D"}, true).
		AddOptArgument("instrument_type").AddOptArgument("instrument_group_type").AddOptArgument("currency").
		Handler(makeHandler("GET", "instruments/%v/leverages", []string{"instrument"},
		[]string{"expiration_date", "issuer_id", "market_view", "instrument_type", "instrument_group_type", "currency"}))

	defTransp.AddCommand(string(api.InstrumentLeverageFiltersCmd)).Description("InstrumentLeverageFiltersCmd").
		AddArgument("instrument").Handler(makeHandler("GET", "instruments/%v/leverages/filters", []string{"instrument"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentOptionPairsCmd)).Description("InstrumentOptionPairsCmd").
		AddArgument("instrument").Handler(makeHandler("GET", "instruments/%v/option_pairs", []string{"instrument"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentOptionPairFiltersCmd)).Description("InstrumentOptionPairFiltersCmd").
		AddArgument("instrument").Handler(makeHandler("GET", "instruments/%v/option_pairs/filters", []string{"instrument"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentLookupCmd)).Description("InstrumentLookupCmd").
		AddFullArgument("type", "Lookup type", []string{"market_id_identifier", "isin_code_currency_market_id"}, false).
		AddFullArgument("lookup", "Format for market_id_identifier: [market_id]:[identifier].\nFormat for isin_code_currency_market_id: [isin]:[currency]:[market_id]", []string{}, false).
		Handler(makeHandler("GET", "instruments/lookup/%v/%v", []string{"type", "lookup"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentSectorsCmd)).Description("InstrumentSectorCmd").TTLHours(12).
		AddFullArgument("sectors", "List of sectors to filter. Separated with comma.", []string{}, true).
		Handler(makeHandler("GET", "instruments/sectors/%v", []string{"sectors"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentTypesCmd)).Description("InstrumentTypesCmd").TTLHours(12).
		AddFullArgument("types", "List of types to filter. Separated with comma.", []string{}, true).
		Handler(makeHandler("GET", "instruments/types/%v", []string{"types"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentUnderlyingsCmd)).Description("InstrumentUnderlyingsCmd").
		AddFullArgument("type", "Derivative type", []string{"leverage", "option_pair"}, false).
		AddArgument("currency").
		Handler(makeHandler("GET", "instruments/underlyings/%v/%v", []string{"type", "currency"}, []string{}))

	defTransp.AddCommand(string(api.ListsCmd)).Description("ListsCmd").TTLHours(12).
		Handler(makeHandler("GET", "lists", []string{}, []string{}))

	defTransp.AddCommand(string(api.ListCmd)).Description("ListCmd").TTLHours(12).
		AddArgument("id").Handler(makeHandler("GET", "lists/%v", []string{"id"}, []string{}))

	defTransp.AddCommand(string(api.MarketCmd)).Description("MarketCmd").TTLHours(12).
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, true).
		Handler(makeHandler("GET", "markets/%v", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.SearchNewsCmd)).Description("SearchNewsCmd").
		Handler(makeHandler("GET", "news", []string{}, []string{}))

	defTransp.AddCommand(string(api.NewsCmd)).Description("NewsCmd").
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "news/%v", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.NewsSourcesCmd)).Description("NewsSourcesCmd").
		Handler(makeHandler("GET", "news_sources", []string{}, []string{}))

	defTransp.AddCommand(string(api.RealtimeAccessCmd)).Description("RealtimeAccessCmd").
		Handler(makeHandler("GET", "realtime_access", []string{}, []string{}))

	defTransp.AddCommand(string(api.TickSizeCmd)).Description("TickSizeCmd").TTLHours(12).
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, true).
		Handler(makeHandler("GET", "tick_sizes/%v", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.TradableInfoCmd)).Description("TradableInfoCmd").
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "tradables/info/%s", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.TradableIntradayCmd)).Description("TradableIntradayCmd").
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "tradables/intraday/%s", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.TradableTradesCmd)).Description("TradableTradesCmd").
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "tradables/trades/%v", []string{"ids"}, []string{}))

	return
}
<commit_msg>Added cachable on some commands<commit_after>package transports

import (
	"github.com/Forau/yanngo/api"
	"github.com/Forau/yanngo/httpcli"

	"encoding/json"

	"fmt"
)

func NewDefaultTransport(endpoint string, user, pass, rawPem []byte) (transp api.TransportHandler, err error) {
	restcli := httpcli.NewRestClient(endpoint, user, pass, rawPem)

	defTransp := make(api.RequestCommandTransport)
	transp = defTransp

	makeHandler := func(method, path string, pathArgs, postArgs []string) func(api.Params) (json.RawMessage, error) {
		return func(p api.Params) (json.RawMessage, error) {
			parsedPath := p.Sprintf(path, pathArgs...)
			res, err := restcli.Execute(method, parsedPath, p.SubParams(postArgs...))
			fmt.Printf("\nGot response from http: %+v\n\n", string(res))
			return res, err
		}
	}

	defTransp.AddCommand(string(api.SessionCmd)).Description("Get the current session from last login").
		Handler(makeHandler("SPECIAL", "session", []string{}, []string{}))

	defTransp.AddCommand(string(api.AccountsCmd)).Description("Get list of accounts").TTLHours(12).
		Handler(makeHandler("GET", "accounts", []string{}, []string{}))

	defTransp.AddCommand(string(api.AccountCmd)).Description("Get account info").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.AccountLedgersCmd)).Description("AccountLedgersCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/ledgers", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.AccountOrdersCmd)).Description("AccountOrdersCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/orders", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.CreateOrderCmd)).Description("CreateOrderCmd").
		AddArgument("accno").
		AddArgument("identifier").
		AddArgument("market_id").
		AddArgument("price").
		AddArgument("currency").
		AddArgument("volume").
		AddFullArgument("side", "Buy or Sell", []string{"BUY", "SELL"}, false).
		AddFullArgument("order_type", "The order type", []string{"FAK", "FOK", "LIMIT", "STOP_LIMIT", "STOP_TRAILING", "OCO"}, true).
		AddOptArgument("valid_until").
		AddOptArgument("open_volume").
		AddOptArgument("reference").
		AddFullArgument("activation_condition", "Used for stop loss orders", []string{"STOP_ACTPRICE_PERC", "STOP_ACTPRICE", "MANUAL", "OCO_STOP_ACTPRICE"}, true).
		AddOptArgument("trigger_value").
		AddFullArgument("trigger_condition", "Condition to trigger", []string{"<=", ">="}, true).
		AddOptArgument("target_value").
		Handler(makeHandler("POST", "accounts/%v/orders", []string{"accno"},
		[]string{"identifier", "market_id", "price", "currency", "volume", "side", "order_type", "valid_until", "open_volume",
			"reference", "activation_condition", "trigger_value", "trigger_condition", "target_value"}))

	defTransp.AddCommand(string(api.ActivateOrderCmd)).Description("ActivateOrderCmd").
		AddArgument("accno").AddArgument("order_id").
		Handler(makeHandler("PUT", "accounts/%v/orders/%v/activate", []string{"accno", "order_id"}, []string{}))

	defTransp.AddCommand(string(api.UpdateOrderCmd)).Description("UpdateOrderCmd").
		AddArgument("accno").AddArgument("order_id").
		AddArgument("price").
		AddArgument("currency").
		AddArgument("volume").
		Handler(makeHandler("PUT", "accounts/%v/orders/%v", []string{"accno", "order_id"},
		[]string{"price", "currency", "volume"}))

	defTransp.AddCommand(string(api.DeleteOrderCmd)).Description("DeleteOrderCmd").
		AddArgument("accno").AddArgument("order_id").
		Handler(makeHandler("DELETE", "accounts/%v/orders/%v", []string{"accno", "order_id"}, []string{}))

	defTransp.AddCommand(string(api.AccountPositionsCmd)).Description("AccountPositionsCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/positions", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.AccountTradesCmd)).Description("AccountTradesCmd").
		AddArgument("accno").Handler(makeHandler("GET", "accounts/%v/trades", []string{"accno"}, []string{}))

	defTransp.AddCommand(string(api.CountriesCmd)).Description("CountriesCmd").TTLHours(12).
		AddFullArgument("countries", "Countries to query. Coma separated list", []string{}, true).
		Handler(makeHandler("GET", "countries/%v", []string{"countries"}, []string{}))

	defTransp.AddCommand(string(api.IndicatorsCmd)).Description("IndicatorsCmd").TTLHours(12).
		AddFullArgument("indicators", "Indicators to query. Format: SRC:ID,...", []string{}, true).
		Handler(makeHandler("GET", "indicators/%v", []string{"indicators"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentsCmd)).Description("InstrumentsCmd").TTLHours(12).
		AddArgument("instruments").Handler(makeHandler("GET", "instruments/%v", []string{"instruments"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentSearchCmd)).Description("InstrumentSearchCmd").
		AddArgument("query").AddOptArgument("instrument_group_type").AddOptArgument("limit").AddOptArgument("offset").
		AddFullArgument("fuzzy", "", []string{"true", "false"}, true).
		Handler(makeHandler("GET", "instruments", []string{}, []string{"query", "instrument_group_type", "limit", "offset", "fuzzy"}))

	defTransp.AddCommand(string(api.InstrumentLeveragesCmd)).Description("InstrumentLeveragesCmd").TTLHours(12).
		AddArgument("instrument").
		AddOptArgument("expiration_date").AddOptArgument("issuer_id").
		AddFullArgument("market_view", "Filter on market view", []string{"U", "D"}, true).
		AddOptArgument("instrument_type").AddOptArgument("instrument_group_type").AddOptArgument("currency").
		Handler(makeHandler("GET", "instruments/%v/leverages", []string{"instrument"},
		[]string{"expiration_date", "issuer_id", "market_view", "instrument_type", "instrument_group_type", "currency"}))

	defTransp.AddCommand(string(api.InstrumentLeverageFiltersCmd)).Description("InstrumentLeverageFiltersCmd").TTLHours(12).
		AddArgument("instrument").Handler(makeHandler("GET", "instruments/%v/leverages/filters", []string{"instrument"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentOptionPairsCmd)).Description("InstrumentOptionPairsCmd").TTLHours(12).
		AddArgument("instrument").Handler(makeHandler("GET", "instruments/%v/option_pairs", []string{"instrument"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentOptionPairFiltersCmd)).Description("InstrumentOptionPairFiltersCmd").TTLHours(12).
		AddArgument("instrument").Handler(makeHandler("GET", "instruments/%v/option_pairs/filters", []string{"instrument"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentLookupCmd)).Description("InstrumentLookupCmd").TTLHours(12).
		AddFullArgument("type", "Lookup type", []string{"market_id_identifier", "isin_code_currency_market_id"}, false).
		AddFullArgument("lookup", "Format for market_id_identifier: [market_id]:[identifier].\nFormat for isin_code_currency_market_id: [isin]:[currency]:[market_id]", []string{}, false).
		Handler(makeHandler("GET", "instruments/lookup/%v/%v", []string{"type", "lookup"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentSectorsCmd)).Description("InstrumentSectorCmd").TTLHours(12).
		AddFullArgument("sectors", "List of sectors to filter. Separated with comma.", []string{}, true).
		Handler(makeHandler("GET", "instruments/sectors/%v", []string{"sectors"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentTypesCmd)).Description("InstrumentTypesCmd").TTLHours(12).
		AddFullArgument("types", "List of types to filter. Separated with comma.", []string{}, true).
		Handler(makeHandler("GET", "instruments/types/%v", []string{"types"}, []string{}))

	defTransp.AddCommand(string(api.InstrumentUnderlyingsCmd)).Description("InstrumentUnderlyingsCmd").TTLHours(12).
		AddFullArgument("type", "Derivative type", []string{"leverage", "option_pair"}, false).
		AddArgument("currency").
		Handler(makeHandler("GET", "instruments/underlyings/%v/%v", []string{"type", "currency"}, []string{}))

	defTransp.AddCommand(string(api.ListsCmd)).Description("ListsCmd").TTLHours(12).
		Handler(makeHandler("GET", "lists", []string{}, []string{}))

	defTransp.AddCommand(string(api.ListCmd)).Description("ListCmd").TTLHours(12).
		AddArgument("id").Handler(makeHandler("GET", "lists/%v", []string{"id"}, []string{}))

	defTransp.AddCommand(string(api.MarketCmd)).Description("MarketCmd").TTLHours(12).
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, true).
		Handler(makeHandler("GET", "markets/%v", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.SearchNewsCmd)).Description("SearchNewsCmd").
		Handler(makeHandler("GET", "news", []string{}, []string{}))

	defTransp.AddCommand(string(api.NewsCmd)).Description("NewsCmd").
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "news/%v", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.NewsSourcesCmd)).Description("NewsSourcesCmd").TTLHours(12).
		Handler(makeHandler("GET", "news_sources", []string{}, []string{}))

	defTransp.AddCommand(string(api.RealtimeAccessCmd)).Description("RealtimeAccessCmd").
		Handler(makeHandler("GET", "realtime_access", []string{}, []string{}))

	defTransp.AddCommand(string(api.TickSizeCmd)).Description("TickSizeCmd").TTLHours(12).
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, true).
		Handler(makeHandler("GET", "tick_sizes/%v", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.TradableInfoCmd)).Description("TradableInfoCmd").TTLHours(12).
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "tradables/info/%s", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.TradableIntradayCmd)).Description("TradableIntradayCmd").
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "tradables/intraday/%s", []string{"ids"}, []string{}))

	defTransp.AddCommand(string(api.TradableTradesCmd)).Description("TradableTradesCmd").
		AddFullArgument("ids", "List of id's. Comma separated", []string{}, false).
		Handler(makeHandler("GET", "tradables/trades/%v", []string{"ids"}, []string{}))

	return
}
<|endoftext|>


<commit_before>// Copyright 2016 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// Packages the static files in a .go file.
//go:generate go run ../package/main.go -out static_files_gen.go ../../../web

// dlibox drives the dlibox LED strip on a Raspberry Pi. It runs a web server
// for remote control.
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"runtime/pprof"
	"syscall"

	"github.com/kardianos/osext"
	"github.com/maruel/dlibox/go/donotuse/host"
	"github.com/maruel/interrupt"
)

func mainImpl() error {
	thisFile, err := osext.Executable()
	if err != nil {
		return err
	}

	cpuprofile := flag.String("cpuprofile", "", "dump CPU profile in file")
	port := flag.Int("port", 8010, "http port to listen on")
	verbose := flag.Bool("verbose", false, "enable log output")
	fake := flag.Bool("fake", false, "use a terminal mock, useful to test without the hardware")
	flag.Parse()
	if flag.NArg() != 0 {
		return fmt.Errorf("unexpected argument: %s", flag.Args())
	}

	if !*verbose {
		log.SetOutput(ioutil.Discard)
	}

	interrupt.HandleCtrlC()
	defer interrupt.Set()
	chanSignal := make(chan os.Signal)
	go func() {
		<-chanSignal
		interrupt.Set()
	}()
	signal.Notify(chanSignal, syscall.SIGTERM)

	var properties []string
	if *cpuprofile != "" {
		// Run with cpuprofile, then use 'go tool pprof' to analyze it. See
		// http://blog.golang.org/profiling-go-programs for more details.
		f, err := os.Create(*cpuprofile)
		if err != nil {
			return err
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
		properties = append(properties, "profiled=1")
	}

	// Initialize pio.
	if _, err := host.Init(); err != nil {
		return err
	}

	// Config.
	config := ConfigMgr{}
	config.ResetDefault()
	if err := config.Load(); err != nil {
		log.Printf("Loading config failed: %v", err)
	}
	defer config.Close()

	b, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		return err
	}
	log.Printf("Config:\n%s", string(b))

	// Initialize modules.

	bus, err := initMQTT(&config.Settings.MQTT)
	if err != nil {
		// Non-fatal.
		log.Printf("MQTT not connected: %v", err)
	}

	_, err = initDisplay(bus, &config.Settings.Display)
	if err != nil {
		// Non-fatal.
		log.Printf("Display not connected: %v", err)
	}

	leds, end, properties2, fps, err := initLEDs(*fake, &config.Settings.APA102)
	if err != nil {
		return err
	}
	defer end()
	properties = append(properties, properties2...)

	p, err := initPainter(bus, leds, fps, &config.Settings.Painter, &config.LRU)
	if err != nil {
		return err
	}
	defer p.Close()

	_, err = initWeb(bus, *port, &config.Config)
	if err != nil {
		return err
	}

	if err = initButton(bus, nil, &config.Settings.Button); err != nil {
		// Non-fatal.
		log.Printf("Button not connected: %v", err)
	}

	if err = initIR(bus, &config.Settings.IR); err != nil {
		// Non-fatal.
		log.Printf("IR not connected: %v", err)
	}

	if err = initPIR(bus, &config.Settings.PIR); err != nil {
		// Non-fatal.
		log.Printf("PIR not connected: %v", err)
	}

	if err = initAlarms(bus, &config.Settings.Alarms); err != nil {
		return err
	}
	//service, err := initmDNS(*port, properties)
	//if err != nil {
	//	return err
	//}
	//defer service.Close()

	return watchFile(thisFile)
}

func main() {
	if err := mainImpl(); err != nil {
		fmt.Fprintf(os.Stderr, "\ndlibox: %s.\n", err)
		os.Exit(1)
	}
}
<commit_msg>Stop logging the config, publish it instead.<commit_after>// Copyright 2016 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// Packages the static files in a .go file.
//go:generate go run ../package/main.go -out static_files_gen.go ../../../web

// dlibox drives the dlibox LED strip on a Raspberry Pi. It runs a web server
// for remote control.
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"runtime/pprof"
	"syscall"

	"github.com/kardianos/osext"
	"github.com/maruel/dlibox/go/donotuse/host"
	"github.com/maruel/dlibox/go/modules"
	"github.com/maruel/interrupt"
)

func mainImpl() error {
	thisFile, err := osext.Executable()
	if err != nil {
		return err
	}

	cpuprofile := flag.String("cpuprofile", "", "dump CPU profile in file")
	port := flag.Int("port", 8010, "http port to listen on")
	verbose := flag.Bool("verbose", false, "enable log output")
	fake := flag.Bool("fake", false, "use a terminal mock, useful to test without the hardware")
	flag.Parse()
	if flag.NArg() != 0 {
		return fmt.Errorf("unexpected argument: %s", flag.Args())
	}

	if !*verbose {
		log.SetOutput(ioutil.Discard)
	}

	interrupt.HandleCtrlC()
	defer interrupt.Set()
	chanSignal := make(chan os.Signal)
	go func() {
		<-chanSignal
		interrupt.Set()
	}()
	signal.Notify(chanSignal, syscall.SIGTERM)

	var properties []string
	if *cpuprofile != "" {
		// Run with cpuprofile, then use 'go tool pprof' to analyze it. See
		// http://blog.golang.org/profiling-go-programs for more details.
		f, err := os.Create(*cpuprofile)
		if err != nil {
			return err
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
		properties = append(properties, "profiled=1")
	}

	// Initialize pio.
	if _, err := host.Init(); err != nil {
		return err
	}

	// Config.
	config := ConfigMgr{}
	config.ResetDefault()
	if err := config.Load(); err != nil {
		log.Printf("Loading config failed: %v", err)
	}
	defer config.Close()

	b, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		return err
	}

	// Initialize modules.

	bus, err := initMQTT(&config.Settings.MQTT)
	if err != nil {
		// Non-fatal.
		log.Printf("MQTT not connected: %v", err)
		log.Printf("Config:\n%s", string(b))
	}
	// Publish the config as a retained message.
	if err := bus.Publish(modules.Message{"config", b}, modules.MinOnce, true); err != nil {
		log.Printf("Publishing failued: %v", err)
	}

	_, err = initDisplay(bus, &config.Settings.Display)
	if err != nil {
		// Non-fatal.
		log.Printf("Display not connected: %v", err)
	}

	leds, end, properties2, fps, err := initLEDs(*fake, &config.Settings.APA102)
	if err != nil {
		return err
	}
	defer end()
	properties = append(properties, properties2...)

	p, err := initPainter(bus, leds, fps, &config.Settings.Painter, &config.LRU)
	if err != nil {
		return err
	}
	defer p.Close()

	_, err = initWeb(bus, *port, &config.Config)
	if err != nil {
		return err
	}

	if err = initButton(bus, nil, &config.Settings.Button); err != nil {
		// Non-fatal.
		log.Printf("Button not connected: %v", err)
	}

	if err = initIR(bus, &config.Settings.IR); err != nil {
		// Non-fatal.
		log.Printf("IR not connected: %v", err)
	}

	if err = initPIR(bus, &config.Settings.PIR); err != nil {
		// Non-fatal.
		log.Printf("PIR not connected: %v", err)
	}

	if err = initAlarms(bus, &config.Settings.Alarms); err != nil {
		return err
	}
	//service, err := initmDNS(*port, properties)
	//if err != nil {
	//	return err
	//}
	//defer service.Close()

	return watchFile(thisFile)
}

func main() {
	if err := mainImpl(); err != nil {
		fmt.Fprintf(os.Stderr, "\ndlibox: %s.\n", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package posix

import (
	"os"
	"strings"
	"syscall"

	co "github.com/lunixbochs/usercorn/go/kernel/common"
)

func (k *PosixKernel) Read(fd co.Fd, buf co.Obuf, size co.Len) uint64 {
	tmp := make([]byte, size)
	n, err := syscall.Read(int(fd), tmp)
	if err != nil {
		return Errno(err)
	}
	if err := buf.Pack(tmp[:n]); err != nil {
		return UINT64_MAX // FIXME
	}
	return uint64(n)
}

func (k *PosixKernel) Write(fd co.Fd, buf co.Buf, size co.Len) uint64 {
	tmp := make([]byte, size)
	if err := buf.Unpack(tmp); err != nil {
		return UINT64_MAX // FIXME
	}
	n, err := syscall.Write(int(fd), tmp)
	if err != nil {
		return Errno(err)
	}
	return uint64(n)
}

func (k *PosixKernel) Open(path string, mode int, flags uint32) uint64 {
	if strings.Contains(path, "/lib/") {
		path = k.U.PrefixPath(path, false)
	}
	fd, err := syscall.Open(path, mode, flags)
	if err != nil {
		return Errno(err)
	}
	return uint64(fd)
}

func (k *PosixKernel) Close(fd co.Fd) uint64 {
	// FIXME: temporary hack to preserve output on program exit
	if fd == 2 {
		return 0
	}
	return Errno(syscall.Close(int(fd)))
}

func (k *PosixKernel) Lseek(fd co.Fd, offset co.Off, whence int) uint64 {
	off, err := syscall.Seek(int(fd), int64(offset), whence)
	if err != nil {
		return Errno(err)
	}
	return uint64(off)
}

func (k *PosixKernel) Fstat(fd co.Fd, buf co.Buf) uint64 {
	var stat syscall.Stat_t
	if err := syscall.Fstat(int(fd), &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}

func (k *PosixKernel) Lstat(path string, buf co.Buf) uint64 {
	var stat syscall.Stat_t
	if err := syscall.Lstat(path, &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}

func (k *PosixKernel) Stat(path string, buf co.Buf) uint64 {
	// TODO: centralize path hook
	if strings.Contains(path, "/lib/") {
		path = k.U.PrefixPath(path, false)
	}
	var stat syscall.Stat_t
	if err := syscall.Stat(path, &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}

func (k *PosixKernel) Getcwd(buf co.Buf, size co.Len) uint64 {
	wd, _ := os.Getwd()
	size -= 1
	if co.Len(len(wd)) > size {
		wd = wd[:size]
	}
	if err := buf.Pack(wd + "\x00"); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}

func (k *PosixKernel) Access(path string, amode uint32) uint64 {
	// TODO: portability
	return Errno(syscall.Access(path, amode))
}

func (k *PosixKernel) Readv(fd co.Fd, iov co.Buf, count uint64) uint64 {
	var read uint64
	for vec := range iovecIter(iov, count, k.U.Bits()) {
		tmp := make([]byte, vec.Len)
		n, err := syscall.Read(int(fd), tmp)
		if err != nil {
			return Errno(err)
		}
		read += uint64(n)
		k.U.MemWrite(vec.Base, tmp[:n])
	}
	return read
}

func (k *PosixKernel) Writev(fd co.Fd, iov co.Buf, count uint64) uint64 {
	var written uint64
	for vec := range iovecIter(iov, count, k.U.Bits()) {
		data, _ := k.U.MemRead(vec.Base, vec.Len)
		n, err := syscall.Write(int(fd), data)
		if err != nil {
			return Errno(err)
		}
		written += uint64(n)
	}
	return written
}

func (k *PosixKernel) Chmod(path string, mode uint32) uint64 {
	return Errno(syscall.Chmod(path, mode))
}

func (k *PosixKernel) Fchmod(fd int, mode uint32) uint64 {
	return Errno(syscall.Fchmod(fd, mode))
}

func (k *PosixKernel) Chown(path string, uid, gid int) uint64 {
	return Errno(syscall.Chown(path, uid, gid))
}

func (k *PosixKernel) Fchown(fd, uid, gid int) uint64 {
	return Errno(syscall.Fchown(fd, uid, gid))
}

func (k *PosixKernel) Lchown(path string, uid, gid int) uint64 {
	return Errno(syscall.Lchown(path, uid, gid))
}

func (k *PosixKernel) Dup(oldFd co.Fd) uint64 {
	if newFd, err := syscall.Dup(int(oldFd)); err != nil {
		return Errno(err)
	} else {
		return uint64(newFd)
	}
}

func (k *PosixKernel) Dup2(oldFd co.Fd, newFd co.Fd) uint64 {
	if err := syscall.Dup2(int(oldFd), int(newFd)); err != nil {
		return Errno(err)
	}
	return uint64(newFd)
}

func (k *PosixKernel) Readlink(path string, buf co.Buf, size co.Len) uint64 {
	// TODO: full proc emulation layer
	// maybe have a syscall pre-hook for this after ghostrace makes it generic
	// or specifically have path hooks and use that to implement prefix as well
	var name string
	var err error
	if path == "/proc/self/exe" && k.U.OS() == "linux" {
		name = k.U.Exe()
	} else {
		name, err = os.Readlink(path)
		if err != nil {
			return UINT64_MAX // FIXME
		}
	}
	if len(name) > int(size)-1 {
		name = name[:size-1]
	}
	if err := buf.Pack([]byte(name + "\x00")); err != nil {
		return UINT64_MAX // FIXME
	}
	return uint64(len(name))
}

func (k *PosixKernel) Symlink(src, dst string) uint64 {
	return Errno(syscall.Symlink(src, dst))
}

func (k *PosixKernel) Link(src, dst string) uint64 {
	return Errno(syscall.Link(src, dst))
}

func (k *PosixKernel) Openat(dirfd co.Fd, path string, flags int, mode uint32) uint64 {
	// TODO: flags might be different per arch
	return openat_native(int(dirfd), path, flags, mode)
}

func (k *PosixKernel) Chdir(path string) uint64 {
	if err := os.Chdir(path); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}

func (k *PosixKernel) Chroot(path string) uint64 {
	return Errno(syscall.Chroot(path))
}
<commit_msg>implement pipe()<commit_after>package posix

import (
	"os"
	"strings"
	"syscall"

	co "github.com/lunixbochs/usercorn/go/kernel/common"
)

func (k *PosixKernel) Read(fd co.Fd, buf co.Obuf, size co.Len) uint64 {
	tmp := make([]byte, size)
	n, err := syscall.Read(int(fd), tmp)
	if err != nil {
		return Errno(err)
	}
	if err := buf.Pack(tmp[:n]); err != nil {
		return UINT64_MAX // FIXME
	}
	return uint64(n)
}

func (k *PosixKernel) Write(fd co.Fd, buf co.Buf, size co.Len) uint64 {
	tmp := make([]byte, size)
	if err := buf.Unpack(tmp); err != nil {
		return UINT64_MAX // FIXME
	}
	n, err := syscall.Write(int(fd), tmp)
	if err != nil {
		return Errno(err)
	}
	return uint64(n)
}

func (k *PosixKernel) Open(path string, mode int, flags uint32) uint64 {
	if strings.Contains(path, "/lib/") {
		path = k.U.PrefixPath(path, false)
	}
	fd, err := syscall.Open(path, mode, flags)
	if err != nil {
		return Errno(err)
	}
	return uint64(fd)
}

func (k *PosixKernel) Close(fd co.Fd) uint64 {
	// FIXME: temporary hack to preserve output on program exit
	if fd == 2 {
		return 0
	}
	return Errno(syscall.Close(int(fd)))
}

func (k *PosixKernel) Lseek(fd co.Fd, offset co.Off, whence int) uint64 {
	off, err := syscall.Seek(int(fd), int64(offset), whence)
	if err != nil {
		return Errno(err)
	}
	return uint64(off)
}

func (k *PosixKernel) Fstat(fd co.Fd, buf co.Buf) uint64 {
	var stat syscall.Stat_t
	if err := syscall.Fstat(int(fd), &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}

func (k *PosixKernel) Lstat(path string, buf co.Buf) uint64 {
	var stat syscall.Stat_t
	if err := syscall.Lstat(path, &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}

func (k *PosixKernel) Stat(path string, buf co.Buf) uint64 {
	// TODO: centralize path hook
	if strings.Contains(path, "/lib/") {
		path = k.U.PrefixPath(path, false)
	}
	var stat syscall.Stat_t
	if err := syscall.Stat(path, &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}

func (k *PosixKernel) Getcwd(buf co.Buf, size co.Len) uint64 {
	wd, _ := os.Getwd()
	size -= 1
	if co.Len(len(wd)) > size {
		wd = wd[:size]
	}
	if err := buf.Pack(wd + "\x00"); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}

func (k *PosixKernel) Access(path string, amode uint32) uint64 {
	// TODO: portability
	return Errno(syscall.Access(path, amode))
}

func (k *PosixKernel) Readv(fd co.Fd, iov co.Buf, count uint64) uint64 {
	var read uint64
	for vec := range iovecIter(iov, count, k.U.Bits()) {
		tmp := make([]byte, vec.Len)
		n, err := syscall.Read(int(fd), tmp)
		if err != nil {
			return Errno(err)
		}
		read += uint64(n)
		k.U.MemWrite(vec.Base, tmp[:n])
	}
	return read
}

func (k *PosixKernel) Writev(fd co.Fd, iov co.Buf, count uint64) uint64 {
	var written uint64
	for vec := range iovecIter(iov, count, k.U.Bits()) {
		data, _ := k.U.MemRead(vec.Base, vec.Len)
		n, err := syscall.Write(int(fd), data)
		if err != nil {
			return Errno(err)
		}
		written += uint64(n)
	}
	return written
}

func (k *PosixKernel) Chmod(path string, mode uint32) uint64 {
	return Errno(syscall.Chmod(path, mode))
}

func (k *PosixKernel) Fchmod(fd int, mode uint32) uint64 {
	return Errno(syscall.Fchmod(fd, mode))
}

func (k *PosixKernel) Chown(path string, uid, gid int) uint64 {
	return Errno(syscall.Chown(path, uid, gid))
}

func (k *PosixKernel) Fchown(fd, uid, gid int) uint64 {
	return Errno(syscall.Fchown(fd, uid, gid))
}

func (k *PosixKernel) Lchown(path string, uid, gid int) uint64 {
	return Errno(syscall.Lchown(path, uid, gid))
}

func (k *PosixKernel) Dup(oldFd co.Fd) uint64 {
	if newFd, err := syscall.Dup(int(oldFd)); err != nil {
		return Errno(err)
	} else {
		return uint64(newFd)
	}
}

func (k *PosixKernel) Dup2(oldFd co.Fd, newFd co.Fd) uint64 {
	if err := syscall.Dup2(int(oldFd), int(newFd)); err != nil {
		return Errno(err)
	}
	return uint64(newFd)
}

func (k *PosixKernel) Readlink(path string, buf co.Buf, size co.Len) uint64 {
	// TODO: full proc emulation layer
	// maybe have a syscall pre-hook for this after ghostrace makes it generic
	// or specifically have path hooks and use that to implement prefix as well
	var name string
	var err error
	if path == "/proc/self/exe" && k.U.OS() == "linux" {
		name = k.U.Exe()
	} else {
		name, err = os.Readlink(path)
		if err != nil {
			return UINT64_MAX // FIXME
		}
	}
	if len(name) > int(size)-1 {
		name = name[:size-1]
	}
	if err := buf.Pack([]byte(name + "\x00")); err != nil {
		return UINT64_MAX // FIXME
	}
	return uint64(len(name))
}

func (k *PosixKernel) Symlink(src, dst string) uint64 {
	return Errno(syscall.Symlink(src, dst))
}

func (k *PosixKernel) Link(src, dst string) uint64 {
	return Errno(syscall.Link(src, dst))
}

func (k *PosixKernel) Openat(dirfd co.Fd, path string, flags int, mode uint32) uint64 {
	// TODO: flags might be different per arch
	return openat_native(int(dirfd), path, flags, mode)
}

func (k *PosixKernel) Chdir(path string) uint64 {
	if err := os.Chdir(path); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}

func (k *PosixKernel) Chroot(path string) uint64 {
	return Errno(syscall.Chroot(path))
}

func (k *PosixKernel) Pipe(files co.Buf) uint64 {
	var fds [2]int
	err := syscall.Pipe(fds[:])
	if err == nil {
		if err := files.Pack(fds); err != nil {
			return UINT64_MAX // FIXME
		}
	}
	return Errno(err)
}
<|endoftext|>


<commit_before>package sparta

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"testing"

	"github.com/Sirupsen/logrus"
)

type StructHandler1 struct {
}

func (handler *StructHandler1) handler(event *json.RawMessage,
	context *LambdaContext,
	w http.ResponseWriter,
	logger *logrus.Logger) {
	fmt.Fprintf(w, "StructHandler1 handler")
}

type StructHandler2 struct {
}

func (handler *StructHandler2) handler(event *json.RawMessage,
	context *LambdaContext,
	w http.ResponseWriter,
	logger *logrus.Logger) {
	fmt.Fprintf(w, "StructHandler1 handler")
}

func testLambdaStructData() []*LambdaAWSInfo {
	var lambdaFunctions []*LambdaAWSInfo

	handler1 := &StructHandler1{}
	lambdaFn1 := NewLambda(LambdaExecuteARN, handler1.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn1)

	handler2 := &StructHandler2{}
	lambdaFn2 := NewLambda(LambdaExecuteARN, handler2.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn2)

	return lambdaFunctions
}

func testLambdaDoubleStructPtrData() []*LambdaAWSInfo {
	var lambdaFunctions []*LambdaAWSInfo

	handler1 := &StructHandler1{}
	lambdaFn1 := NewLambda(LambdaExecuteARN, handler1.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn1)

	handler2 := &StructHandler1{}
	lambdaFn2 := NewLambda(LambdaExecuteARN, handler2.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn2)

	return lambdaFunctions
}

func userDefinedCustomResource1(requestType string,
	stackID string,
	properties map[string]interface{},
	logger *logrus.Logger) (map[string]interface{}, error) {
	return nil, nil
}

func userDefinedCustomResource2(requestType string,
	stackID string,
	properties map[string]interface{},
	logger *logrus.Logger) (map[string]interface{}, error) {
	return nil, nil
}

func TestStruct(t *testing.T) {
	logger, err := NewLogger("info")
	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		testLambdaStructData(),
		nil,
		nil,
		"testBuildID",
		"S3Bucket",
		"",
		"",
		&templateWriter,
		nil,
		logger)
	if nil != err {
		t.Fatal(err.Error())
	}
}

func TestDoubleRefStruct(t *testing.T) {
	logger, err := NewLogger("info")
	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		testLambdaDoubleStructPtrData(),
		nil,
		nil,
		"testBuildID",
		"S3Bucket",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil == err {
		t.Fatal("Failed to enforce lambda function uniqueness")
	}
}

func TestCustomResource(t *testing.T) {
	logger, err := NewLogger("info")
	lambdaFuncs := testLambdaStructData()
	lambdaFuncs[0].RequireCustomResource(IAMRoleDefinition{},
		userDefinedCustomResource1,
		nil,
		nil)

	lambdaFuncs[1].RequireCustomResource(IAMRoleDefinition{},
		userDefinedCustomResource2,
		nil,
		nil)

	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		lambdaFuncs,
		nil,
		nil,
		"testBuildID",
		"S3Bucket",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil != err {
		t.Fatal("Failed to accept unique user CustomResource functions")
	}
}

func TestDoubleRefCustomResource(t *testing.T) {
	logger, err := NewLogger("info")
	lambdaFuncs := testLambdaStructData()

	for _, eachLambda := range lambdaFuncs {
		eachLambda.RequireCustomResource(IAMRoleDefinition{},
			userDefinedCustomResource1,
			nil,
			nil)
	}
	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		lambdaFuncs,
		nil,
		nil,
		"testBuildID",
		"S3Bucket",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil == err {
		t.Fatal("Failed to reject duplicate user CustomResource functions")
	}
}

func SignatureVersion(t *testing.T) {
	logger, err := NewLogger("info")

	lambdaFunctions := testLambdaDoubleStructPtrData()
	lambdaFunctions[0].Options = &LambdaFunctionOptions{
		SpartaOptions: &SpartaOptions{
			Name: fmt.Sprintf("Handler0"),
		},
	}
	lambdaFunctions[1].Options = &LambdaFunctionOptions{
		SpartaOptions: &SpartaOptions{
			Name: fmt.Sprintf("Handler1"),
		},
	}
	var templateWriter bytes.Buffer
	err = Provision(true,
		"TestOverlappingLambdas",
		"",
		lambdaFunctions,
		nil,
		nil,
		"testBuildID",
		"S3Bucket",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil != err {
		t.Fatal("Failed to respect duplicate lambdas with user supplied names")
	} else {
		t.Logf("Rejected duplicate lambdas")
	}
}

func TestUserDefinedOverlappingLambdaNames(t *testing.T) {
	logger, err := NewLogger("info")

	lambdaFunctions := testLambdaDoubleStructPtrData()
	for _, eachLambda := range lambdaFunctions {
		eachLambda.Options = &LambdaFunctionOptions{
			SpartaOptions: &SpartaOptions{
				Name: fmt.Sprintf("HandlerX"),
			},
		}
	}

	var templateWriter bytes.Buffer
	err = Provision(true,
		"TestOverlappingLambdas",
		"",
		lambdaFunctions,
		nil,
		nil,
		"testBuildID",
		"S3Bucket",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil == err {
		t.Fatal("Failed to reject duplicate lambdas with overlapping user supplied names")
	} else {
		t.Logf("Rejected overlapping user supplied names")
	}
}
<commit_msg>Use env var for S3 test bucket<commit_after>package sparta

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/Sirupsen/logrus"
	"net/http"
	"os"
	"testing"
)

type StructHandler1 struct {
}

func (handler *StructHandler1) handler(event *json.RawMessage,
	context *LambdaContext,
	w http.ResponseWriter,
	logger *logrus.Logger) {
	fmt.Fprintf(w, "StructHandler1 handler")
}

type StructHandler2 struct {
}

func (handler *StructHandler2) handler(event *json.RawMessage,
	context *LambdaContext,
	w http.ResponseWriter,
	logger *logrus.Logger) {
	fmt.Fprintf(w, "StructHandler1 handler")
}

func testLambdaStructData() []*LambdaAWSInfo {
	var lambdaFunctions []*LambdaAWSInfo

	handler1 := &StructHandler1{}
	lambdaFn1 := NewLambda(LambdaExecuteARN, handler1.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn1)

	handler2 := &StructHandler2{}
	lambdaFn2 := NewLambda(LambdaExecuteARN, handler2.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn2)

	return lambdaFunctions
}

func testLambdaDoubleStructPtrData() []*LambdaAWSInfo {
	var lambdaFunctions []*LambdaAWSInfo

	handler1 := &StructHandler1{}
	lambdaFn1 := NewLambda(LambdaExecuteARN, handler1.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn1)

	handler2 := &StructHandler1{}
	lambdaFn2 := NewLambda(LambdaExecuteARN, handler2.handler, nil)
	lambdaFunctions = append(lambdaFunctions, lambdaFn2)

	return lambdaFunctions
}

func userDefinedCustomResource1(requestType string,
	stackID string,
	properties map[string]interface{},
	logger *logrus.Logger) (map[string]interface{}, error) {
	return nil, nil
}

func userDefinedCustomResource2(requestType string,
	stackID string,
	properties map[string]interface{},
	logger *logrus.Logger) (map[string]interface{}, error) {
	return nil, nil
}

func TestStruct(t *testing.T) {
	logger, err := NewLogger("info")
	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		testLambdaStructData(),
		nil,
		nil,
		os.Getenv("S3_BUCKET"),
		"testBuildID",
		"",
		"",
		"",
		&templateWriter,
		nil,
		logger)
	if nil != err {
		t.Fatal(err.Error())
	}
}

func TestDoubleRefStruct(t *testing.T) {
	logger, err := NewLogger("info")
	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		testLambdaDoubleStructPtrData(),
		nil,
		nil,
		os.Getenv("S3_BUCKET"),
		"testBuildID",
		"",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil == err {
		t.Fatal("Failed to enforce lambda function uniqueness")
	}
}

func TestCustomResource(t *testing.T) {
	logger, err := NewLogger("info")
	lambdaFuncs := testLambdaStructData()
	lambdaFuncs[0].RequireCustomResource(IAMRoleDefinition{},
		userDefinedCustomResource1,
		nil,
		nil)

	lambdaFuncs[1].RequireCustomResource(IAMRoleDefinition{},
		userDefinedCustomResource2,
		nil,
		nil)

	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		lambdaFuncs,
		nil,
		nil,
		os.Getenv("S3_BUCKET"),
		"testBuildID",
		"",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil != err {
		t.Fatal("Failed to accept unique user CustomResource functions")
	}
}

func TestDoubleRefCustomResource(t *testing.T) {
	logger, err := NewLogger("info")
	lambdaFuncs := testLambdaStructData()

	for _, eachLambda := range lambdaFuncs {
		eachLambda.RequireCustomResource(IAMRoleDefinition{},
			userDefinedCustomResource1,
			nil,
			nil)
	}
	var templateWriter bytes.Buffer
	err = Provision(true,
		"SampleProvision",
		"",
		lambdaFuncs,
		nil,
		nil,
		os.Getenv("S3_BUCKET"),
		"testBuildID",
		"",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil == err {
		t.Fatal("Failed to reject duplicate user CustomResource functions")
	}
}

func SignatureVersion(t *testing.T) {
	logger, err := NewLogger("info")

	lambdaFunctions := testLambdaDoubleStructPtrData()
	lambdaFunctions[0].Options = &LambdaFunctionOptions{
		SpartaOptions: &SpartaOptions{
			Name: fmt.Sprintf("Handler0"),
		},
	}
	lambdaFunctions[1].Options = &LambdaFunctionOptions{
		SpartaOptions: &SpartaOptions{
			Name: fmt.Sprintf("Handler1"),
		},
	}
	var templateWriter bytes.Buffer
	err = Provision(true,
		"TestOverlappingLambdas",
		"",
		lambdaFunctions,
		nil,
		nil,
		os.Getenv("S3_BUCKET"),
		"testBuildID",
		"",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil != err {
		t.Fatal("Failed to respect duplicate lambdas with user supplied names")
	} else {
		t.Logf("Rejected duplicate lambdas")
	}
}

func TestUserDefinedOverlappingLambdaNames(t *testing.T) {
	logger, err := NewLogger("info")

	lambdaFunctions := testLambdaDoubleStructPtrData()
	for _, eachLambda := range lambdaFunctions {
		eachLambda.Options = &LambdaFunctionOptions{
			SpartaOptions: &SpartaOptions{
				Name: fmt.Sprintf("HandlerX"),
			},
		}
	}

	var templateWriter bytes.Buffer
	err = Provision(true,
		"TestOverlappingLambdas",
		"",
		lambdaFunctions,
		nil,
		nil,
		os.Getenv("S3_BUCKET"),
		"testBuildID",
		"",
		"",
		"",
		&templateWriter,
		nil,
		logger)

	if nil == err {
		t.Fatal("Failed to reject duplicate lambdas with overlapping user supplied names")
	} else {
		t.Logf("Rejected overlapping user supplied names")
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

package ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run test with GOMAXPROCS=8.

import (
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/go/ssa"
	"code.google.com/p/go.tools/go/ssa/ssautil"
)

func allPackages() []string {
	var pkgs []string
	root := filepath.Join(runtime.GOROOT(), "src/pkg") + string(os.PathSeparator)
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		// Prune the search if we encounter any of these names:
		switch filepath.Base(path) {
		case "testdata", ".hg":
			return filepath.SkipDir
		}
		if info.IsDir() {
			pkg := strings.TrimPrefix(path, root)
			switch pkg {
			case "builtin", "pkg", "code.google.com":
				return filepath.SkipDir // skip these subtrees
			case "":
				return nil // ignore root of tree
			}
			pkgs = append(pkgs, pkg)
		}

		return nil
	})
	return pkgs
}

func TestStdlib(t *testing.T) {
	// Load, parse and type-check the program.
	t0 := time.Now()

	var conf loader.Config
	conf.SourceImports = true
	if _, err := conf.FromArgs(allPackages(), true); err != nil {
		t.Errorf("FromArgs failed: %v", err)
		return
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()

	runtime.GC()
	var memstats runtime.MemStats
	runtime.ReadMemStats(&memstats)
	alloc := memstats.Alloc

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssa.Create(iprog, mode)

	t2 := time.Now()

	// Build SSA.
	prog.BuildAll()

	t3 := time.Now()

	runtime.GC()
	runtime.ReadMemStats(&memstats)

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Dump some statistics.
	allFuncs := ssautil.AllFunctions(prog)
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB:                  ", int64(memstats.Alloc-alloc)/1000000)
}
<commit_msg>go/loader: convert directory separators to slash when enumerating packages.<commit_after>// Copyright 2013 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.

package ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run test with GOMAXPROCS=8.

import (
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/go/ssa"
	"code.google.com/p/go.tools/go/ssa/ssautil"
)

func allPackages() []string {
	var pkgs []string
	root := filepath.Join(runtime.GOROOT(), "src/pkg") + string(os.PathSeparator)
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		// Prune the search if we encounter any of these names:
		switch filepath.Base(path) {
		case "testdata", ".hg":
			return filepath.SkipDir
		}
		if info.IsDir() {
			pkg := filepath.ToSlash(strings.TrimPrefix(path, root))
			switch pkg {
			case "builtin", "pkg":
				return filepath.SkipDir // skip these subtrees
			case "":
				return nil // ignore root of tree
			}
			pkgs = append(pkgs, pkg)
		}

		return nil
	})
	return pkgs
}

func TestStdlib(t *testing.T) {
	// Load, parse and type-check the program.
	t0 := time.Now()

	var conf loader.Config
	conf.SourceImports = true
	if _, err := conf.FromArgs(allPackages(), true); err != nil {
		t.Errorf("FromArgs failed: %v", err)
		return
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()

	runtime.GC()
	var memstats runtime.MemStats
	runtime.ReadMemStats(&memstats)
	alloc := memstats.Alloc

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssa.Create(iprog, mode)

	t2 := time.Now()

	// Build SSA.
	prog.BuildAll()

	t3 := time.Now()

	runtime.GC()
	runtime.ReadMemStats(&memstats)

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Dump some statistics.
	allFuncs := ssautil.AllFunctions(prog)
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB:                  ", int64(memstats.Alloc-alloc)/1000000)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/gorilla/feeds"
	"time"
)

func main() {
	t := time.Now()

	feed := &feeds.Feed{
		Title: "Test feed.",
		Link: &feeds.Link{Href:"http://oyasirazu.dip.jp/"},
		Description:"Test.",
		Author: &feeds.Author{"mikoto2000", "mikoto2000@gmail.com"},
		Created: t,
	}

	rss, _ := feed.ToRss()

	fmt.Println(rss)
}
<commit_msg>Added "feed item" in "golang/feeds".<commit_after>package main

import (
	"fmt"
	"github.com/gorilla/feeds"
	"time"
)

func main() {
	t := time.Now()

	feed := &feeds.Feed{
		Title: "Test feed.",
		Link: &feeds.Link{Href:"http://oyasirazu.dip.jp/"},
		Description:"Test.",
		Author: &feeds.Author{"mikoto2000", "mikoto2000@gmail.com"},
		Created: t,
	}

	feed.Items = []*feeds.Item{
		&feeds.Item{
			Title: "Test feed item.",
			Link: &feeds.Link{Href:"http://oyasirazu.dip.jp/item"},
			Description:"Test.",
			Author: &feeds.Author{"mikoto2000", "mikoto2000@gmail.com"},
			Created: t,
		},
	}

	rss, _ := feed.ToRss()

	fmt.Println(rss)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"strconv"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/autoscaling"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSASGNotification_basic(t *testing.T) {
	var asgn autoscaling.DescribeNotificationConfigurationsOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckASGNDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccASGNotificationConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example", []string{"foobar1-terraform-test"}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},
		},
	})
}

func TestAccAWSASGNotification_update(t *testing.T) {
	var asgn autoscaling.DescribeNotificationConfigurationsOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckASGNDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccASGNotificationConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example", []string{"foobar1-terraform-test"}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},

			resource.TestStep{
				Config: testAccASGNotificationConfig_update,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example", []string{"foobar1-terraform-test", "barfoo-terraform-test"}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},
		},
	})
}

func TestAccAWSASGNotification_Pagination(t *testing.T) {
	var asgn autoscaling.DescribeNotificationConfigurationsOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckASGNDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccASGNotificationConfig_pagination,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example",
						[]string{
							"foobar3-terraform-test-0",
							"foobar3-terraform-test-1",
							"foobar3-terraform-test-2",
							"foobar3-terraform-test-3",
							"foobar3-terraform-test-4",
							"foobar3-terraform-test-5",
							"foobar3-terraform-test-6",
							"foobar3-terraform-test-7",
							"foobar3-terraform-test-8",
							"foobar3-terraform-test-9",
							"foobar3-terraform-test-10",
							"foobar3-terraform-test-11",
							"foobar3-terraform-test-12",
							"foobar3-terraform-test-13",
							"foobar3-terraform-test-14",
							"foobar3-terraform-test-15",
							"foobar3-terraform-test-16",
							"foobar3-terraform-test-17",
							"foobar3-terraform-test-18",
							"foobar3-terraform-test-19",
						}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},
		},
	})
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ASG Notification ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
		opts := &autoscaling.DescribeNotificationConfigurationsInput{
			AutoScalingGroupNames: aws.StringSlice(groups),
			MaxRecords:            aws.Int64(100),
		}

		resp, err := conn.DescribeNotificationConfigurations(opts)
		if err != nil {
			return fmt.Errorf("Error describing notifications: %s", err)
		}

		*asgn = *resp

		return nil
	}
}

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

		groups := []*string{aws.String("foobar1-terraform-test")}
		conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
		opts := &autoscaling.DescribeNotificationConfigurationsInput{
			AutoScalingGroupNames: groups,
		}

		resp, err := conn.DescribeNotificationConfigurations(opts)
		if err != nil {
			return fmt.Errorf("Error describing notifications")
		}

		if len(resp.NotificationConfigurations) != 0 {
			fmt.Errorf("Error finding notification descriptions")
		}

	}
	return nil
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ASG Notification ID is set")
		}

		if len(asgn.NotificationConfigurations) == 0 {
			return fmt.Errorf("Error: no ASG Notifications found")
		}

		// build a unique list of groups, notification types
		gRaw := make(map[string]bool)
		nRaw := make(map[string]bool)

		for _, n := range asgn.NotificationConfigurations {
			if *n.TopicARN == rs.Primary.Attributes["topic_arn"] {
				gRaw[*n.AutoScalingGroupName] = true
				nRaw[*n.NotificationType] = true
			}
		}

		// Grab the keys here as the list of Groups
		var gList []string
		for k, _ := range gRaw {
			gList = append(gList, k)
		}

		// Grab the keys here as the list of Types
		var nList []string
		for k, _ := range nRaw {
			nList = append(nList, k)
		}

		typeCount, _ := strconv.Atoi(rs.Primary.Attributes["notifications.#"])

		if len(nList) != typeCount {
			return fmt.Errorf("Error: Bad ASG Notification count, expected (%d), got (%d)", typeCount, len(nList))
		}

		groupCount, _ := strconv.Atoi(rs.Primary.Attributes["group_names.#"])

		if len(gList) != groupCount {
			return fmt.Errorf("Error: Bad ASG Group count, expected (%d), got (%d)", typeCount, len(gList))
		}

		return nil
	}
}

const testAccASGNotificationConfig_basic = `
resource "aws_sns_topic" "topic_example" {
  name = "user-updates-topic"
}

resource "aws_launch_configuration" "foobar" {
  name = "foobarautoscaling-terraform-test"
  image_id = "ami-21f78e11"
  instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "bar" {
  availability_zones = ["us-west-2a"]
  name = "foobar1-terraform-test"
  max_size = 1
  min_size = 1
  health_check_grace_period = 100
  health_check_type = "ELB"
  desired_capacity = 1
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_notification" "example" {
  group_names     = ["${aws_autoscaling_group.bar.name}"]
  notifications  = [
	"autoscaling:EC2_INSTANCE_LAUNCH",
	"autoscaling:EC2_INSTANCE_TERMINATE",
  ]
  topic_arn = "${aws_sns_topic.topic_example.arn}"
}
`

const testAccASGNotificationConfig_update = `
resource "aws_sns_topic" "user_updates" {
  name = "user-updates-topic"
}

resource "aws_launch_configuration" "foobar" {
  name = "foobarautoscaling-terraform-test"
  image_id = "ami-21f78e11"
  instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "bar" {
  availability_zones = ["us-west-2a"]
  name = "foobar1-terraform-test"
  max_size = 1
  min_size = 1
  health_check_grace_period = 100
  health_check_type = "ELB"
  desired_capacity = 1
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_group" "foo" {
  availability_zones = ["us-west-2b"]
  name = "barfoo-terraform-test"
  max_size = 1
  min_size = 1
  health_check_grace_period = 200
  health_check_type = "ELB"
  desired_capacity = 1
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_notification" "example" {
	group_names     = [
	"${aws_autoscaling_group.bar.name}",
	"${aws_autoscaling_group.foo.name}",
	]
	notifications  = [
		"autoscaling:EC2_INSTANCE_LAUNCH",
		"autoscaling:EC2_INSTANCE_TERMINATE",
		"autoscaling:EC2_INSTANCE_LAUNCH_ERROR"
	]
	topic_arn = "${aws_sns_topic.user_updates.arn}"
}`

const testAccASGNotificationConfig_pagination = `
resource "aws_sns_topic" "user_updates" {
  name = "user-updates-topic"
}

resource "aws_launch_configuration" "foobar" {
  image_id = "ami-21f78e11"
  instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "bar" {
  availability_zones = ["us-west-2a"]
  count = 20
  name = "foobar3-terraform-test-${count.index}"
  max_size = 1
  min_size = 0
  health_check_grace_period = 300
  health_check_type = "ELB"
  desired_capacity = 0
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_notification" "example" {
  group_names = [
    "${aws_autoscaling_group.bar.*.name}",
  ]
  notifications  = [
    "autoscaling:EC2_INSTANCE_LAUNCH",
    "autoscaling:EC2_INSTANCE_TERMINATE",
    "autoscaling:TEST_NOTIFICATION"
  ]
	topic_arn = "${aws_sns_topic.user_updates.arn}"
}`
<commit_msg>fix resource name in test<commit_after>package aws

import (
	"fmt"
	"strconv"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/autoscaling"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSASGNotification_basic(t *testing.T) {
	var asgn autoscaling.DescribeNotificationConfigurationsOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckASGNDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccASGNotificationConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example", []string{"foobar1-terraform-test"}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},
		},
	})
}

func TestAccAWSASGNotification_update(t *testing.T) {
	var asgn autoscaling.DescribeNotificationConfigurationsOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckASGNDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccASGNotificationConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example", []string{"foobar1-terraform-test"}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},

			resource.TestStep{
				Config: testAccASGNotificationConfig_update,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example", []string{"foobar1-terraform-test", "barfoo-terraform-test"}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},
		},
	})
}

func TestAccAWSASGNotification_Pagination(t *testing.T) {
	var asgn autoscaling.DescribeNotificationConfigurationsOutput

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckASGNDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccASGNotificationConfig_pagination,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckASGNotificationExists("aws_autoscaling_notification.example",
						[]string{
							"foobar3-terraform-test-0",
							"foobar3-terraform-test-1",
							"foobar3-terraform-test-2",
							"foobar3-terraform-test-3",
							"foobar3-terraform-test-4",
							"foobar3-terraform-test-5",
							"foobar3-terraform-test-6",
							"foobar3-terraform-test-7",
							"foobar3-terraform-test-8",
							"foobar3-terraform-test-9",
							"foobar3-terraform-test-10",
							"foobar3-terraform-test-11",
							"foobar3-terraform-test-12",
							"foobar3-terraform-test-13",
							"foobar3-terraform-test-14",
							"foobar3-terraform-test-15",
							"foobar3-terraform-test-16",
							"foobar3-terraform-test-17",
							"foobar3-terraform-test-18",
							"foobar3-terraform-test-19",
						}, &asgn),
					testAccCheckAWSASGNotificationAttributes("aws_autoscaling_notification.example", &asgn),
				),
			},
		},
	})
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ASG Notification ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
		opts := &autoscaling.DescribeNotificationConfigurationsInput{
			AutoScalingGroupNames: aws.StringSlice(groups),
			MaxRecords:            aws.Int64(100),
		}

		resp, err := conn.DescribeNotificationConfigurations(opts)
		if err != nil {
			return fmt.Errorf("Error describing notifications: %s", err)
		}

		*asgn = *resp

		return nil
	}
}

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

		groups := []*string{aws.String("foobar1-terraform-test")}
		conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
		opts := &autoscaling.DescribeNotificationConfigurationsInput{
			AutoScalingGroupNames: groups,
		}

		resp, err := conn.DescribeNotificationConfigurations(opts)
		if err != nil {
			return fmt.Errorf("Error describing notifications")
		}

		if len(resp.NotificationConfigurations) != 0 {
			fmt.Errorf("Error finding notification descriptions")
		}

	}
	return nil
}

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

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ASG Notification ID is set")
		}

		if len(asgn.NotificationConfigurations) == 0 {
			return fmt.Errorf("Error: no ASG Notifications found")
		}

		// build a unique list of groups, notification types
		gRaw := make(map[string]bool)
		nRaw := make(map[string]bool)

		for _, n := range asgn.NotificationConfigurations {
			if *n.TopicARN == rs.Primary.Attributes["topic_arn"] {
				gRaw[*n.AutoScalingGroupName] = true
				nRaw[*n.NotificationType] = true
			}
		}

		// Grab the keys here as the list of Groups
		var gList []string
		for k, _ := range gRaw {
			gList = append(gList, k)
		}

		// Grab the keys here as the list of Types
		var nList []string
		for k, _ := range nRaw {
			nList = append(nList, k)
		}

		typeCount, _ := strconv.Atoi(rs.Primary.Attributes["notifications.#"])

		if len(nList) != typeCount {
			return fmt.Errorf("Error: Bad ASG Notification count, expected (%d), got (%d)", typeCount, len(nList))
		}

		groupCount, _ := strconv.Atoi(rs.Primary.Attributes["group_names.#"])

		if len(gList) != groupCount {
			return fmt.Errorf("Error: Bad ASG Group count, expected (%d), got (%d)", typeCount, len(gList))
		}

		return nil
	}
}

const testAccASGNotificationConfig_basic = `
resource "aws_sns_topic" "topic_example" {
  name = "user-updates-topic"
}

resource "aws_launch_configuration" "foobar" {
  name = "foobarautoscaling-terraform-test"
  image_id = "ami-21f78e11"
  instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "bar" {
  availability_zones = ["us-west-2a"]
  name = "foobar1-terraform-test"
  max_size = 1
  min_size = 1
  health_check_grace_period = 100
  health_check_type = "ELB"
  desired_capacity = 1
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_notification" "example" {
  group_names     = ["${aws_autoscaling_group.bar.name}"]
  notifications  = [
	"autoscaling:EC2_INSTANCE_LAUNCH",
	"autoscaling:EC2_INSTANCE_TERMINATE",
  ]
  topic_arn = "${aws_sns_topic.topic_example.arn}"
}
`

const testAccASGNotificationConfig_update = `
resource "aws_sns_topic" "topic_example" {
  name = "user-updates-topic"
}

resource "aws_launch_configuration" "foobar" {
  name = "foobarautoscaling-terraform-test"
  image_id = "ami-21f78e11"
  instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "bar" {
  availability_zones = ["us-west-2a"]
  name = "foobar1-terraform-test"
  max_size = 1
  min_size = 1
  health_check_grace_period = 100
  health_check_type = "ELB"
  desired_capacity = 1
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_group" "foo" {
  availability_zones = ["us-west-2b"]
  name = "barfoo-terraform-test"
  max_size = 1
  min_size = 1
  health_check_grace_period = 200
  health_check_type = "ELB"
  desired_capacity = 1
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_notification" "example" {
	group_names     = [
	"${aws_autoscaling_group.bar.name}",
	"${aws_autoscaling_group.foo.name}",
	]
	notifications  = [
		"autoscaling:EC2_INSTANCE_LAUNCH",
		"autoscaling:EC2_INSTANCE_TERMINATE",
		"autoscaling:EC2_INSTANCE_LAUNCH_ERROR"
	]
	topic_arn = "${aws_sns_topic.topic_example.arn}"
}`

const testAccASGNotificationConfig_pagination = `
resource "aws_sns_topic" "user_updates" {
  name = "user-updates-topic"
}

resource "aws_launch_configuration" "foobar" {
  image_id = "ami-21f78e11"
  instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "bar" {
  availability_zones = ["us-west-2a"]
  count = 20
  name = "foobar3-terraform-test-${count.index}"
  max_size = 1
  min_size = 0
  health_check_grace_period = 300
  health_check_type = "ELB"
  desired_capacity = 0
  force_delete = true
  termination_policies = ["OldestInstance"]
  launch_configuration = "${aws_launch_configuration.foobar.name}"
}

resource "aws_autoscaling_notification" "example" {
  group_names = [
    "${aws_autoscaling_group.bar.*.name}",
  ]
  notifications  = [
    "autoscaling:EC2_INSTANCE_LAUNCH",
    "autoscaling:EC2_INSTANCE_TERMINATE",
    "autoscaling:TEST_NOTIFICATION"
  ]
	topic_arn = "${aws_sns_topic.user_updates.arn}"
}`
<|endoftext|>


<commit_before>package walnut

import (
	"regexp"
	"strconv"
	"time"
)

var (
	_TruthyRegexp = regexp.MustCompile(`^[ \t]*(true|yes|on)`)
	_FalsyRegexp  = regexp.MustCompile(`^[ \t]*(false|no|off)`)
	_IntRegexp    = regexp.MustCompile(`^[ \t]*([\+\-]?\d+)`)
	_FloatRegexp  = regexp.MustCompile(`^[ \t]*([\+\-]?\d+(?:\.\d+)?)`)
	_TimeRegexp   = regexp.MustCompile(
		`^[ \t]*(\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [\-\+]\d{4})`)
)

// Attempts to extract a boolean value from the beginning of `in`.
func readBool(in []byte) (bool, int) {
	if m := _TruthyRegexp.FindIndex(in); m != nil {
		return true, m[1]
	}
	if m := _FalsyRegexp.FindIndex(in); m != nil {
		return false, m[1]
	}

	return false, 0
}

// Attempts to extract a signed integer from the beginning of `in`.
func readInt64(in []byte) (int64, int) {
	m := _IntRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	num := string(in[m[2]:m[3]])
	v, err := strconv.ParseInt(num, 10, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a floating point value from the beginning of `in`.
func readFloat64(in []byte) (float64, int) {
	m := _FloatRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := strconv.ParseFloat(slice, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a timestamp from the beginning of `in`.
func readTime(in []byte) (time.Time, int) {
	m := _TimeRegexp.FindSubmatchIndex(in)
	if m == nil {
		return time.Time{}, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := time.Parse("2006-01-02 15:04:05 -0700", slice)
	if err != nil {
		return time.Time{}, 0
	}

	return v, m[3]
}
<commit_msg>Implement string literal parsing<commit_after>package walnut

import (
	"regexp"
	"strconv"
	"time"
)

var (
	_TruthyRegexp = regexp.MustCompile(`^[ \t]*(true|yes|on)`)
	_FalsyRegexp  = regexp.MustCompile(`^[ \t]*(false|no|off)`)
	_IntRegexp    = regexp.MustCompile(`^[ \t]*([\+\-]?\d+)`)
	_FloatRegexp  = regexp.MustCompile(`^[ \t]*([\+\-]?\d+(?:\.\d+)?)`)
	_TimeRegexp   = regexp.MustCompile(
		`^[ \t]*(\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [\-\+]\d{4})`)
)

// Attempts to extract a string literal from the beginning of `in`.
func readBool(in []byte) (bool, int) {
	if m := _TruthyRegexp.FindIndex(in); m != nil {
		return true, m[1]
	}
	if m := _FalsyRegexp.FindIndex(in); m != nil {
		return false, m[1]
	}

	return false, 0
}

// Attempts to extract a signed integer from the beginning of `in`.
func readInt64(in []byte) (int64, int) {
	m := _IntRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	num := string(in[m[2]:m[3]])
	v, err := strconv.ParseInt(num, 10, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a floating point value from the beginning of `in`.
func readFloat64(in []byte) (float64, int) {
	m := _FloatRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := strconv.ParseFloat(slice, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a timestamp from the beginning of `in`.
func readString(in []byte) (string, int) {
	start := 0
	for start < len(in) && (in[start] == ' ' || in[start] == '\t') {
		start++
	}

	if len(in)-start < 2 || in[start] != '"' {
		return "", 0
	}

	i := start + 1 // jump the first double quote
	end := -1
	escaped := false

	for end == -1 {
		if i == len(in) {
			// end of input reached before finding a closing quote
			return "", 0
		}

		b := in[i]

		switch {
		case b <= 0x20:
			// control characters aren't inside a string literal
			return "", 0
		case escaped:
			escaped = false
		case b == '\\':
			escaped = true
		case b == '"':
			end = i
		}

		i++
	}

	v, err := strconv.Unquote(string(in[start : end+1]))
	if err != nil {
		return "", 0
	}

	return v, end + 1
}

// Attempts to extract a timestamp from the beginning of `in`.
func readTime(in []byte) (time.Time, int) {
	m := _TimeRegexp.FindSubmatchIndex(in)
	if m == nil {
		return time.Time{}, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := time.Parse("2006-01-02 15:04:05 -0700", slice)
	if err != nil {
		return time.Time{}, 0
	}

	return v, m[3]
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"os"
	"regexp"

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

var certificateArnRegex = regexp.MustCompile(`^arn:aws:acm:[^:]+:[^:]+:certificate/.+$`)

func TestAccAwsAcmResource_emailValidation(t *testing.T) {
	if os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN") == "" {
		t.Skip("Environment variable ACM_CERTIFICATE_ROOT_DOMAIN is not set")
	}

	root_zone_domain := os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN")

	rInt1 := acctest.RandInt()

	domain := fmt.Sprintf("tf-acc-%d.%s", rInt1, root_zone_domain)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAcmCertificateDestroy,
		Steps: []resource.TestStep{
			// Test that we can request a certificate
			resource.TestStep{
				Config: testAccAcmCertificateConfigWithEMailValidation(domain),
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.#", "0"),
					resource.TestMatchResourceAttr("aws_acm_certificate.cert", "validation_emails.0", regexp.MustCompile(`^[^@]+@.+$`)),
				),
			},
			resource.TestStep{
				ResourceName:      "aws_acm_certificate.cert",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})

}
func TestAccAwsAcmResource_certificateIssuingFlow(t *testing.T) {
	if os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN") == "" {
		t.Skip("Environment variable ACM_CERTIFICATE_ROOT_DOMAIN is not set")
	}

	root_zone_domain := os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN")

	rInt1 := acctest.RandInt()

	domain := fmt.Sprintf("tf-acc-%d.%s", rInt1, root_zone_domain)
	sanDomain := fmt.Sprintf("tf-acc-%d-san.%s", rInt1, root_zone_domain)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAcmCertificateDestroy,
		Steps: []resource.TestStep{
			// Test that we can request a certificate
			resource.TestStep{
				Config: testAccAcmCertificateConfig(domain, sanDomain),
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.#", "1"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.0", sanDomain),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Hello", "World"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Foo", "Bar"),
				),
			},
			// Test that we can change the tags
			resource.TestStep{
				Config: testAccAcmCertificateConfigWithChangedTags(domain, sanDomain),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Environment", "Test"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Foo", "Baz"),
				),
			},
			// Test that validation times out if certificate can't be validated
			resource.TestStep{
				Config:      testAccAcmCertificateWithValidationConfig(domain, sanDomain),
				ExpectError: regexp.MustCompile("Expected certificate to be issued but was in state PENDING_VALIDATION"),
			},
			// Test that validation fails if given validation_fqdns don't match
			resource.TestStep{
				Config:      testAccAcmCertificateWithValidationConfigAndWrongFQDN(domain, sanDomain),
				ExpectError: regexp.MustCompile("Certificate needs .* to be set but only .* was passed to validation_record_fqdns"),
			},
			// Test that validation succeeds once we provide the right DNS validation records
			resource.TestStep{
				Config: testAccAcmCertificateWithValidationAndRecordsConfig(root_zone_domain, domain, sanDomain),
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("aws_acm_certificate_validation.cert", "certificate_arn", certificateArnRegex),
				),
			},
			resource.TestStep{
				ResourceName:      "aws_acm_certificate.cert",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccAcmCertificateConfigWithEMailValidation(domain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "EMAIL"
}
`, domain)

}

func testAccAcmCertificateConfig(domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Hello" = "World"
    "Foo" = "Bar"
  }
}
`, domain, sanDomain)
}

func testAccAcmCertificateConfigWithChangedTags(domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Environment" = "Test"
    "Foo" = "Baz"
  }
}
`, domain, sanDomain)
}

func testAccAcmCertificateWithValidationConfig(domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Environment" = "Test"
    "Foo" = "Baz"
  }
}

resource "aws_acm_certificate_validation" "cert" {
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  timeout = "20s"
}
`, domain, sanDomain)
}

func testAccAcmCertificateWithValidationConfigAndWrongFQDN(domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Environment" = "Test"
    "Foo" = "Baz"
  }
}

resource "aws_acm_certificate_validation" "cert" {
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["some-wrong-fqdn.example.com"]
  timeout = "20s"
}
`, domain, sanDomain)
}

func testAccAcmCertificateWithValidationAndRecordsConfig(rootZoneDomain string, domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Environment" = "Test"
    "Foo" = "Baz"
  }
}

data "aws_route53_zone" "zone" {
  name = "%s."
  private_zone = false
}

resource "aws_route53_record" "cert_validation" {
  name = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${data.aws_route53_zone.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl = 60
}

resource "aws_route53_record" "cert_validation_san" {
  name = "${aws_acm_certificate.cert.domain_validation_options.1.resource_record_name}"
  type = "${aws_acm_certificate.cert.domain_validation_options.1.resource_record_type}"
  zone_id = "${data.aws_route53_zone.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.1.resource_record_value}"]
  ttl = 60
}

resource "aws_acm_certificate_validation" "cert" {
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = [
	"${aws_route53_record.cert_validation.fqdn}",
	"${aws_route53_record.cert_validation_san.fqdn}"
  ]
}
`, domain, sanDomain, rootZoneDomain)
}

func testAccCheckAcmCertificateDestroy(s *terraform.State) error {
	acmconn := testAccProvider.Meta().(*AWSClient).acmconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_acm_certificate" {
			continue
		}
		_, err := acmconn.DescribeCertificate(&acm.DescribeCertificateInput{
			CertificateArn: aws.String(rs.Primary.ID),
		})

		if err == nil {
			return fmt.Errorf("Certificate still exists.")
		}

		// Verify the error is what we want
		if !isAWSErr(err, acm.ErrCodeResourceNotFoundException, "") {
			return err
		}
	}

	return nil
}
<commit_msg>r/aws_acm_certificate: Simplify tests, parameterize instead of duplicate<commit_after>package aws

import (
	"fmt"
	"testing"

	"os"
	"regexp"

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

var certificateArnRegex = regexp.MustCompile(`^arn:aws:acm:[^:]+:[^:]+:certificate/.+$`)

func TestAccAwsAcmResource_emailValidation(t *testing.T) {
	if os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN") == "" {
		t.Skip("Environment variable ACM_CERTIFICATE_ROOT_DOMAIN is not set")
	}

	root_zone_domain := os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN")

	rInt1 := acctest.RandInt()

	domain := fmt.Sprintf("tf-acc-%d.%s", rInt1, root_zone_domain)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAcmCertificateDestroy,
		Steps: []resource.TestStep{
			// Test that we can request a certificate
			resource.TestStep{
				Config: testAccAcmCertificateConfigWithEMailValidation(domain),
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.#", "0"),
					resource.TestMatchResourceAttr("aws_acm_certificate.cert", "validation_emails.0", regexp.MustCompile(`^[^@]+@.+$`)),
				),
			},
			resource.TestStep{
				ResourceName:      "aws_acm_certificate.cert",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})

}
func TestAccAwsAcmResource_certificateIssuingFlow(t *testing.T) {
	if os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN") == "" {
		t.Skip("Environment variable ACM_CERTIFICATE_ROOT_DOMAIN is not set")
	}

	root_zone_domain := os.Getenv("ACM_CERTIFICATE_ROOT_DOMAIN")

	rInt1 := acctest.RandInt()

	domain := fmt.Sprintf("tf-acc-%d.%s", rInt1, root_zone_domain)
	sanDomain := fmt.Sprintf("tf-acc-%d-san.%s", rInt1, root_zone_domain)

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAcmCertificateDestroy,
		Steps: []resource.TestStep{
			// Test that we can request a certificate
			resource.TestStep{
				Config: testAccAcmCertificateConfig(
					domain, sanDomain,
					"Hello", "World",
					"Foo", "Bar"),
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("aws_acm_certificate.cert", "arn", certificateArnRegex),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "domain_name", domain),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.#", "1"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "subject_alternative_names.0", sanDomain),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Hello", "World"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Foo", "Bar"),
				),
			},
			// Test that we can change the tags
			resource.TestStep{
				Config: testAccAcmCertificateConfig(
					domain, sanDomain,
					"Environment", "Test",
					"Foo", "Baz"),
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Environment", "Test"),
					resource.TestCheckResourceAttr("aws_acm_certificate.cert", "tags.Foo", "Baz"),
				),
			},
			// Test that validation times out if certificate can't be validated
			resource.TestStep{
				Config:      testAccAcmCertificateWithValidationConfig(domain, sanDomain),
				ExpectError: regexp.MustCompile("Expected certificate to be issued but was in state PENDING_VALIDATION"),
			},
			// Test that validation fails if given validation_fqdns don't match
			resource.TestStep{
				Config:      testAccAcmCertificateWithValidationConfigAndWrongFQDN(domain, sanDomain),
				ExpectError: regexp.MustCompile("Certificate needs .* to be set but only .* was passed to validation_record_fqdns"),
			},
			// Test that validation succeeds once we provide the right DNS validation records
			resource.TestStep{
				Config: testAccAcmCertificateWithValidationAndRecordsConfig(root_zone_domain, domain, sanDomain),
				Check: resource.ComposeTestCheckFunc(
					resource.TestMatchResourceAttr("aws_acm_certificate_validation.cert", "certificate_arn", certificateArnRegex),
				),
			},
			resource.TestStep{
				ResourceName:      "aws_acm_certificate.cert",
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccAcmCertificateConfigWithEMailValidation(domain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "EMAIL"
}
`, domain)

}

func testAccAcmCertificateConfig(domain string, sanDomain string, tag1Key, tag1Value, tag2Key, tag2Value string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "%s" = "%s"
    "%s" = "%s"
  }
}
`, domain, sanDomain, tag1Key, tag1Value, tag2Key, tag2Value)
}

func testAccAcmCertificateWithValidationConfig(domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Environment" = "Test"
    "Foo" = "Baz"
  }
}

resource "aws_acm_certificate_validation" "cert" {
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  timeout = "20s"
}
`, domain, sanDomain)
}

func testAccAcmCertificateWithValidationConfigAndWrongFQDN(domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Environment" = "Test"
    "Foo" = "Baz"
  }
}

resource "aws_acm_certificate_validation" "cert" {
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["some-wrong-fqdn.example.com"]
  timeout = "20s"
}
`, domain, sanDomain)
}

func testAccAcmCertificateWithValidationAndRecordsConfig(rootZoneDomain string, domain string, sanDomain string) string {
	return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
  domain_name = "%s"
  validation_method = "DNS"
  subject_alternative_names = ["%s"]

  tags {
    "Environment" = "Test"
    "Foo" = "Baz"
  }
}

data "aws_route53_zone" "zone" {
  name = "%s."
  private_zone = false
}

resource "aws_route53_record" "cert_validation" {
  name = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${data.aws_route53_zone.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl = 60
}

resource "aws_route53_record" "cert_validation_san" {
  name = "${aws_acm_certificate.cert.domain_validation_options.1.resource_record_name}"
  type = "${aws_acm_certificate.cert.domain_validation_options.1.resource_record_type}"
  zone_id = "${data.aws_route53_zone.zone.id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.1.resource_record_value}"]
  ttl = 60
}

resource "aws_acm_certificate_validation" "cert" {
  certificate_arn = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = [
	"${aws_route53_record.cert_validation.fqdn}",
	"${aws_route53_record.cert_validation_san.fqdn}"
  ]
}
`, domain, sanDomain, rootZoneDomain)
}

func testAccCheckAcmCertificateDestroy(s *terraform.State) error {
	acmconn := testAccProvider.Meta().(*AWSClient).acmconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_acm_certificate" {
			continue
		}
		_, err := acmconn.DescribeCertificate(&acm.DescribeCertificateInput{
			CertificateArn: aws.String(rs.Primary.ID),
		})

		if err == nil {
			return fmt.Errorf("Certificate still exists.")
		}

		// Verify the error is what we want
		if !isAWSErr(err, acm.ErrCodeResourceNotFoundException, "") {
			return err
		}
	}

	return nil
}
<|endoftext|>