<commit_before>// (C) Copyright 2016 Hewlett Packard Enterprise Development LP
//
// Licensed under the Apache License, Version 2.0 (the "License");
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

package oneview

import (
	"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceInterconnects() *schema.Resource {
	return &schema.Resource{
		Read: dataSourceInterconnectsRead,

		Schema: map[string]*schema.Schema{
			"category": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"description": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enclosure_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enclosure_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enclosure_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"host_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"interconnect_ip": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"interconnect_location": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"location_entries": {
							Type:     schema.TypeList,
							Computed: true,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"type": {
										Type:     schema.TypeString,
										Computed: true,
									},
									"value": {
										Type:     schema.TypeString,
										Computed: true,
									},
								},
							},
						},
					},
				},
			},
			"interconnect_mac": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"interconnect_type_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"ip_address_list": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"ip_address": {
							Type:     schema.TypeString,
							Required: true,
						},
						"ip_address_type": {
							Type:     schema.TypeString,
							Required: true,
						},
					},
				},
			},
			"lldp_ip_address_mode": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"lldp_ipv4_address": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"lldp_ipv6_address": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"logical_interconnect_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"model": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
			},
			"product_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"roles": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
			"scopes_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"snmp_configuration": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"category": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"description": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"enabled": {
							Type:     schema.TypeBool,
							Computed: true,
						},
						"name": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"snmp_access": {
							Type:     schema.TypeSet,
							Computed: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
						"trap_destinations": {
							Type:     schema.TypeList,
							Computed: true,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"community_string": {
										Type:     schema.TypeString,
										Computed: true,
									},
									"enet_trap_categories": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
									"fc_trap_categories": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
									"vcm_trap_categories": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
									"trap_destination": {
										Type:     schema.TypeString,
										Required: true,
									},
									"trap_format": {
										Type:     schema.TypeString,
										Optional: true,
										Default:  "SNMPv1",
									},
									"trap_severities": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
								},
							},
						},
						"type": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"uri": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"v3_enabled": {
							Type:     schema.TypeBool,
							Computed: true,
						},
					},
				},
			},
			"type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func dataSourceInterconnectsRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	name := d.Get("name").(string)

	interconnect, err := config.ovClient.GetInterconnectByName(name)
	if err != nil || interconnect.URI.IsNil() {
		d.SetId("")

		return nil
	}

	d.SetId(name)

	d.Set("category", interconnect.Category)
	d.Set("description", interconnect.Description)
	d.Set("enclosure_name", interconnect.EnclosureName)
	d.Set("enclosure_type", interconnect.EnclosureType)
	d.Set("enclosure_uri", interconnect.EnclosureUri.String())
	d.Set("host_name", interconnect.HostName)
	d.Set("interconnect_ip", interconnect.InterconnectIP)
	d.Set("interconnect_mac", interconnect.InterconnectMAC)
	d.Set("interconnect_type_uri", interconnect.InterconnectTypeUri.String())
	d.Set("lldp_ip_address_mode", interconnect.LldpIpAddressMode)
	d.Set("lldp_ipv4_address", interconnect.LldpIpv4Address)
	d.Set("lldp_ipv6_address", interconnect.LldpIpv6Address)
	d.Set("logical_interconnect_uri", interconnect.LogicalInterconnectUri.String())
	d.Set("model", interconnect.Model)
	d.Set("name", interconnect.Name)
	d.Set("product_name", interconnect.ProductName)
	d.Set("scopes_uri", interconnect.ScopesUri)
	d.Set("type", interconnect.Type)
	d.Set("uri", interconnect.URI.String())

	locationEntries := make([]map[string]interface{}, 0,
		len(interconnect.InterconnectLocation.LocationEntries))
	for _, locationEntry := range interconnect.InterconnectLocation.LocationEntries {
		locationEntries = append(locationEntries, map[string]interface{}{
			"type":  locationEntry.Type,
			"value": locationEntry.Value,
		})
	}
	interconnectLocation := make([]map[string]interface{}, 0, 1)
	interconnectLocation = append(interconnectLocation, map[string]interface{}{
		"location_entries": locationEntries,
	})

	d.Set("interconnect_location", interconnectLocation)

	ipAddressList := make([]map[string]interface{}, 0,
		len(interconnect.IpAddressList))
	for _, ipAddress := range interconnect.IpAddressList {
		ipAddressList = append(ipAddressList, map[string]interface{}{
			"ip_address_type": ipAddress.IpAddressType,
			"ip_address":      ipAddress.IpAddress,
		})
	}

	d.Set("ip_address_list", ipAddressList)

	trapDestinations := make([]map[string]interface{}, 0, 1)
	for _, trapDestination := range interconnect.SnmpConfiguration.TrapDestinations {

		enetTrapCategories := make([]interface{}, len(trapDestination.EnetTrapCategories))
		for i, enetTrapCategory := range trapDestination.EnetTrapCategories {
			enetTrapCategories[i] = enetTrapCategory
		}

		fcTrapCategories := make([]interface{}, len(trapDestination.FcTrapCategories))
		for i, fcTrapCategory := range trapDestination.FcTrapCategories {
			fcTrapCategories[i] = fcTrapCategory
		}

		vcmTrapCategories := make([]interface{}, len(trapDestination.VcmTrapCategories))
		for i, vcmTrapCategory := range trapDestination.VcmTrapCategories {
			vcmTrapCategories[i] = vcmTrapCategory
		}

		trapSeverities := make([]interface{}, len(trapDestination.TrapSeverities))
		for i, trapSeverity := range trapDestination.TrapSeverities {
			trapSeverities[i] = trapSeverity
		}

		trapDestinations = append(trapDestinations, map[string]interface{}{
			"trap_destination":     trapDestination.TrapDestination,
			"community_string":     trapDestination.CommunityString,
			"trap_format":          trapDestination.TrapFormat,
			"enet_trap_categories": schema.NewSet(schema.HashString, enetTrapCategories),
			"fc_trap_categories":   schema.NewSet(schema.HashString, fcTrapCategories),
			"vcm_trap_categories":  schema.NewSet(schema.HashString, vcmTrapCategories),
			"trap_severities":      schema.NewSet(schema.HashString, trapSeverities),
		})
	}

	snmpAccess := make([]interface{}, len(interconnect.SnmpConfiguration.SnmpAccess))
	for i, snmpAccessIP := range interconnect.SnmpConfiguration.SnmpAccess {
		snmpAccess[i] = snmpAccessIP
	}

	snmpConfiguration := make([]map[string]interface{}, 0, 1)
	snmpConfiguration = append(snmpConfiguration, map[string]interface{}{
		"category":	    interconnect.SnmpConfiguration.Category,
		"description":      interconnect.SnmpConfiguration.Description,
		"name":             interconnect.SnmpConfiguration.Name,
		"uri":		    interconnect.SnmpConfiguration.URI,
		"enabled":          interconnect.SnmpConfiguration.Enabled,
		"v3_enabled":       interconnect.SnmpConfiguration.V3Enabled,
		"snmp_access":      schema.NewSet(schema.HashString, snmpAccess),
		"type":             interconnect.SnmpConfiguration.Type,
		"trap_destinations": trapDestinations,
	})
	d.Set("snmp_configuration", snmpConfiguration)

	return nil
}
<commit_msg>fixed fmt issues<commit_after>// (C) Copyright 2016 Hewlett Packard Enterprise Development LP
//
// Licensed under the Apache License, Version 2.0 (the "License");
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

package oneview

import (
	"github.com/hashicorp/terraform/helper/schema"
)

func dataSourceInterconnects() *schema.Resource {
	return &schema.Resource{
		Read: dataSourceInterconnectsRead,

		Schema: map[string]*schema.Schema{
			"category": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"description": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enclosure_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enclosure_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enclosure_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"host_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"interconnect_ip": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"interconnect_location": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"location_entries": {
							Type:     schema.TypeList,
							Computed: true,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"type": {
										Type:     schema.TypeString,
										Computed: true,
									},
									"value": {
										Type:     schema.TypeString,
										Computed: true,
									},
								},
							},
						},
					},
				},
			},
			"interconnect_mac": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"interconnect_type_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"ip_address_list": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"ip_address": {
							Type:     schema.TypeString,
							Required: true,
						},
						"ip_address_type": {
							Type:     schema.TypeString,
							Required: true,
						},
					},
				},
			},
			"lldp_ip_address_mode": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"lldp_ipv4_address": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"lldp_ipv6_address": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"logical_interconnect_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"model": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"name": {
				Type:     schema.TypeString,
				Required: true,
			},
			"product_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"roles": {
				Type:     schema.TypeSet,
				Computed: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
			"scopes_uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"snmp_configuration": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"category": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"description": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"enabled": {
							Type:     schema.TypeBool,
							Computed: true,
						},
						"name": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"snmp_access": {
							Type:     schema.TypeSet,
							Computed: true,
							Elem:     &schema.Schema{Type: schema.TypeString},
							Set:      schema.HashString,
						},
						"trap_destinations": {
							Type:     schema.TypeList,
							Computed: true,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"community_string": {
										Type:     schema.TypeString,
										Computed: true,
									},
									"enet_trap_categories": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
									"fc_trap_categories": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
									"vcm_trap_categories": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
									"trap_destination": {
										Type:     schema.TypeString,
										Required: true,
									},
									"trap_format": {
										Type:     schema.TypeString,
										Optional: true,
										Default:  "SNMPv1",
									},
									"trap_severities": {
										Type:     schema.TypeSet,
										Computed: true,
										Elem:     &schema.Schema{Type: schema.TypeString},
										Set:      schema.HashString,
									},
								},
							},
						},
						"type": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"uri": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"v3_enabled": {
							Type:     schema.TypeBool,
							Computed: true,
						},
					},
				},
			},
			"type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"uri": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func dataSourceInterconnectsRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	name := d.Get("name").(string)

	interconnect, err := config.ovClient.GetInterconnectByName(name)
	if err != nil || interconnect.URI.IsNil() {
		d.SetId("")

		return nil
	}

	d.SetId(name)

	d.Set("category", interconnect.Category)
	d.Set("description", interconnect.Description)
	d.Set("enclosure_name", interconnect.EnclosureName)
	d.Set("enclosure_type", interconnect.EnclosureType)
	d.Set("enclosure_uri", interconnect.EnclosureUri.String())
	d.Set("host_name", interconnect.HostName)
	d.Set("interconnect_ip", interconnect.InterconnectIP)
	d.Set("interconnect_mac", interconnect.InterconnectMAC)
	d.Set("interconnect_type_uri", interconnect.InterconnectTypeUri.String())
	d.Set("lldp_ip_address_mode", interconnect.LldpIpAddressMode)
	d.Set("lldp_ipv4_address", interconnect.LldpIpv4Address)
	d.Set("lldp_ipv6_address", interconnect.LldpIpv6Address)
	d.Set("logical_interconnect_uri", interconnect.LogicalInterconnectUri.String())
	d.Set("model", interconnect.Model)
	d.Set("name", interconnect.Name)
	d.Set("product_name", interconnect.ProductName)
	d.Set("scopes_uri", interconnect.ScopesUri)
	d.Set("type", interconnect.Type)
	d.Set("uri", interconnect.URI.String())

	locationEntries := make([]map[string]interface{}, 0,
		len(interconnect.InterconnectLocation.LocationEntries))
	for _, locationEntry := range interconnect.InterconnectLocation.LocationEntries {
		locationEntries = append(locationEntries, map[string]interface{}{
			"type":  locationEntry.Type,
			"value": locationEntry.Value,
		})
	}
	interconnectLocation := make([]map[string]interface{}, 0, 1)
	interconnectLocation = append(interconnectLocation, map[string]interface{}{
		"location_entries": locationEntries,
	})

	d.Set("interconnect_location", interconnectLocation)

	ipAddressList := make([]map[string]interface{}, 0,
		len(interconnect.IpAddressList))
	for _, ipAddress := range interconnect.IpAddressList {
		ipAddressList = append(ipAddressList, map[string]interface{}{
			"ip_address_type": ipAddress.IpAddressType,
			"ip_address":      ipAddress.IpAddress,
		})
	}

	d.Set("ip_address_list", ipAddressList)

	trapDestinations := make([]map[string]interface{}, 0, 1)
	for _, trapDestination := range interconnect.SnmpConfiguration.TrapDestinations {

		enetTrapCategories := make([]interface{}, len(trapDestination.EnetTrapCategories))
		for i, enetTrapCategory := range trapDestination.EnetTrapCategories {
			enetTrapCategories[i] = enetTrapCategory
		}

		fcTrapCategories := make([]interface{}, len(trapDestination.FcTrapCategories))
		for i, fcTrapCategory := range trapDestination.FcTrapCategories {
			fcTrapCategories[i] = fcTrapCategory
		}

		vcmTrapCategories := make([]interface{}, len(trapDestination.VcmTrapCategories))
		for i, vcmTrapCategory := range trapDestination.VcmTrapCategories {
			vcmTrapCategories[i] = vcmTrapCategory
		}

		trapSeverities := make([]interface{}, len(trapDestination.TrapSeverities))
		for i, trapSeverity := range trapDestination.TrapSeverities {
			trapSeverities[i] = trapSeverity
		}

		trapDestinations = append(trapDestinations, map[string]interface{}{
			"trap_destination":     trapDestination.TrapDestination,
			"community_string":     trapDestination.CommunityString,
			"trap_format":          trapDestination.TrapFormat,
			"enet_trap_categories": schema.NewSet(schema.HashString, enetTrapCategories),
			"fc_trap_categories":   schema.NewSet(schema.HashString, fcTrapCategories),
			"vcm_trap_categories":  schema.NewSet(schema.HashString, vcmTrapCategories),
			"trap_severities":      schema.NewSet(schema.HashString, trapSeverities),
		})
	}

	snmpAccess := make([]interface{}, len(interconnect.SnmpConfiguration.SnmpAccess))
	for i, snmpAccessIP := range interconnect.SnmpConfiguration.SnmpAccess {
		snmpAccess[i] = snmpAccessIP
	}

	snmpConfiguration := make([]map[string]interface{}, 0, 1)
	snmpConfiguration = append(snmpConfiguration, map[string]interface{}{
		"category":          interconnect.SnmpConfiguration.Category,
		"description":       interconnect.SnmpConfiguration.Description,
		"name":              interconnect.SnmpConfiguration.Name,
		"uri":               interconnect.SnmpConfiguration.URI,
		"enabled":           interconnect.SnmpConfiguration.Enabled,
		"v3_enabled":        interconnect.SnmpConfiguration.V3Enabled,
		"snmp_access":       schema.NewSet(schema.HashString, snmpAccess),
		"type":              interconnect.SnmpConfiguration.Type,
		"trap_destinations": trapDestinations,
	})
	d.Set("snmp_configuration", snmpConfiguration)

	return nil
}
<|endoftext|>


<commit_before>package namedwebsockets

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/gorilla/websocket"

	"log"
	"strings"
	"github.com/notificator"
	"path/filepath"

	"net/http"
	"container/list"

	"runtime"
)

type ProxyConnection struct {
	// Inherit attributes from PeerConnection struct
	PeerConnection

	// List of connection ids that this proxy connection 'owns'
	peers map[int]bool

	// Whether this proxy connection is writeable
	writeable bool
}

type ProxyWireMessage struct {
	// Proxy message type: "connect", "disconnect", "message", "directmessage"
	Action string

	Source int

	// Recipients' id list (0 === send to all peers)
	Target int

	// Raw message contents
	Payload string
}

var proxyNotifiedList list.List

var counter int

var elem list.Element

func NewProxyConnection(id int, socket *websocket.Conn, isWriteable bool) *ProxyConnection {
	proxyConn := &ProxyConnection{
		PeerConnection: PeerConnection{
			id: id,
			ws: socket,
		},
		writeable: isWriteable,
		peers:     make(map[int]bool),
	}

	return proxyConn
}

// Send a message to the target websocket connection
func (proxy *ProxyConnection) send(action string, source int, target int, payload string) {
	// Construct proxy wire message
	m := ProxyWireMessage{
		Action:  action,
		Source:  source,
		Target:  target,
		Payload: payload,
	}
	messagePayload, err := json.Marshal(m)
	if err != nil {
		return
	}

	proxy.ws.SetWriteDeadline(time.Now().Add(writeWait))
	proxy.ws.WriteMessage(websocket.TextMessage, messagePayload)
}

// readConnectionPump pumps messages from an individual websocket connection to the dispatcher
func (proxy *ProxyConnection) readConnectionPump(sock *NamedWebSocket) {
	defer func() {
		proxy.removeConnection(sock)
	}()
	proxy.ws.SetReadLimit(maxMessageSize)
	proxy.ws.SetReadDeadline(time.Now().Add(pongWait))
	proxy.ws.SetPongHandler(func(string) error { proxy.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
	for {
		opCode, buf, err := proxy.ws.ReadMessage()
		if err != nil || opCode != websocket.TextMessage {
			break
		}

		var message ProxyWireMessage
		err = json.Unmarshal(buf, &message)
		if err != nil {
			continue
		}

		switch message.Action {

		case "connect":

			proxy.peers[message.Target] = true

			// Inform all control connections that this proxy owns this peer connection
			for _, control := range sock.controllers {
				control.send("connect", control.id, message.Target, "")
			}

		case "disconnect":

			delete(proxy.peers, message.Target)

			// Inform all control connections that this proxy no longer owns this peer connection
			for _, control := range sock.controllers {
				control.send("disconnect", control.id, message.Target, "")
			}

		case "message":

			// broadcast message on to given target
			wsBroadcast := &Message{
				source:    message.Source,
				target:    0, // target all connections
				payload:   message.Payload,
				fromProxy: true,
			}

			//log.Printf("Received Proxy Message: %s",message.Payload)

			var notiRecived bool = false

			for e := proxyNotifiedList.Front(); e != nil; e=e.Next() {
				if(message.Payload==e.Value.(string)){
					notiRecived = true
					break
				}
			}

			//create notifications with the url for linux and android
			if(strings.Contains(message.Payload,"http://")&&!notiRecived){

				proxyNotifiedList.PushBack(message.Payload)

				path, err2 := filepath.Abs("Mediascape.png")
				if err2 != nil {
					log.Fatal(err)
				}

				notify = notificator.New(notificator.Options{
					DefaultIcon: path,
					AppName:     "Mediascape",
				})

				if(string(runtime.GOOS)=="linux"&&string(runtime.GOARCH)!="arm"){
					notify.Push("Mediascape", message.Payload, path)
				}else if(string(runtime.GOOS)=="linux"&&string(runtime.GOARCH)=="arm"){
					completUrl := fmt.Sprintf("http://localhost:8182/discoveragent/notification?url=%s", message.Payload)
					response, err := http.Get(completUrl)
					if err != nil {
						log.Printf("Error: %s",err)
					}else{
						defer response.Body.Close()
					}
				}
			}

			sock.broadcastBuffer <- wsBroadcast

		case "directmessage":

			messageSent := false

			// Relay message to control channel that matches target
			for _, control := range sock.controllers {
				if control.id == message.Target {
					control.send("message", message.Source, message.Target, message.Payload)
					messageSent = true
					break
				}
			}

			if !messageSent {
				fmt.Errorf("P2P message target could not be found. Not sent.")
			}

		}
	}
}

// writeConnectionPump keeps an individual websocket connection alive
func (proxy *ProxyConnection) writeConnectionPump(sock *NamedWebSocket) {
	ticker := time.NewTicker(pingPeriod)
	defer func() {
		ticker.Stop()
		proxy.removeConnection(sock)
	}()
	for {
		select {
		case <-ticker.C:
			proxy.ws.SetWriteDeadline(time.Now().Add(writeWait))
			proxy.ws.WriteMessage(websocket.PingMessage, []byte{})
		}
	}
}

// Set up a new NamedWebSocket connection instance
func (proxy *ProxyConnection) addConnection(sock *NamedWebSocket) {
	sock.proxies = append(sock.proxies, proxy)

	if proxy.writeable {
		// Inform this proxy of all the peer connections we own
		for _, peer := range sock.peers {
			proxy.send("connect", proxy.id, peer.id, "")
		}
	}

	// Start connection read/write pumps
	go proxy.writeConnectionPump(sock)
	go proxy.readConnectionPump(sock)
}

// Tear down an existing NamedWebSocket connection instance
func (proxy *ProxyConnection) removeConnection(sock *NamedWebSocket) {
	for i, conn := range sock.proxies {
		if conn.id == proxy.id {
			sock.proxies = append(sock.proxies[:i], sock.proxies[i+1:]...)
			break
		}
	}

	if proxy.writeable {
		// Inform this proxy of all the peer connections we no longer own
		for _, peer := range sock.peers {
			proxy.send("disconnect", proxy.id, peer.id, "")
		}
	}

	proxy.ws.Close()
}
<commit_msg>Update proxy.go<commit_after>package namedwebsockets

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/gorilla/websocket"

	"log"
	"strings"
	"github.com/notificator"
	"path/filepath"

	"net/http"
	"container/list"

	"runtime"
)

type ProxyConnection struct {
	// Inherit attributes from PeerConnection struct
	PeerConnection

	// List of connection ids that this proxy connection 'owns'
	peers map[int]bool

	// Whether this proxy connection is writeable
	writeable bool
}

type ProxyWireMessage struct {
	// Proxy message type: "connect", "disconnect", "message", "directmessage"
	Action string

	Source int

	// Recipients' id list (0 === send to all peers)
	Target int

	// Raw message contents
	Payload string
}

var proxyNotifiedList list.List

var counter int

var elem list.Element

func NewProxyConnection(id int, socket *websocket.Conn, isWriteable bool) *ProxyConnection {
	proxyConn := &ProxyConnection{
		PeerConnection: PeerConnection{
			id: id,
			ws: socket,
		},
		writeable: isWriteable,
		peers:     make(map[int]bool),
	}

	return proxyConn
}

// Send a message to the target websocket connection
func (proxy *ProxyConnection) send(action string, source int, target int, payload string) {
	// Construct proxy wire message
	m := ProxyWireMessage{
		Action:  action,
		Source:  source,
		Target:  target,
		Payload: payload,
	}
	messagePayload, err := json.Marshal(m)
	if err != nil {
		return
	}

	proxy.ws.SetWriteDeadline(time.Now().Add(writeWait))
	proxy.ws.WriteMessage(websocket.TextMessage, messagePayload)
}

// readConnectionPump pumps messages from an individual websocket connection to the dispatcher
func (proxy *ProxyConnection) readConnectionPump(sock *NamedWebSocket) {
	defer func() {
		proxy.removeConnection(sock)
	}()
	proxy.ws.SetReadLimit(maxMessageSize)
	proxy.ws.SetReadDeadline(time.Now().Add(pongWait))
	proxy.ws.SetPongHandler(func(string) error { proxy.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
	for {
		opCode, buf, err := proxy.ws.ReadMessage()
		if err != nil || opCode != websocket.TextMessage {
			break
		}

		var message ProxyWireMessage
		err = json.Unmarshal(buf, &message)
		if err != nil {
			continue
		}

		switch message.Action {

		case "connect":

			proxy.peers[message.Target] = true

			// Inform all control connections that this proxy owns this peer connection
			for _, control := range sock.controllers {
				control.send("connect", control.id, message.Target, "")
			}

		case "disconnect":

			delete(proxy.peers, message.Target)

			// Inform all control connections that this proxy no longer owns this peer connection
			for _, control := range sock.controllers {
				control.send("disconnect", control.id, message.Target, "")
			}

		case "message":

			// broadcast message on to given target
			wsBroadcast := &Message{
				source:    message.Source,
				target:    0, // target all connections
				payload:   message.Payload,
				fromProxy: true,
			}

			//log.Printf("Received Proxy Message: %s",message.Payload)

			var notiRecived bool = false

			for e := proxyNotifiedList.Front(); e != nil; e=e.Next() {
				if(message.Payload==e.Value.(string)){
					notiRecived = true
					break
				}
			}

			//create notifications with the url for linux and android
			if(strings.Contains(message.Payload,"http://")&&!notiRecived){

				proxyNotifiedList.PushBack(message.Payload)
				peerNotifiedList.PushBack(message.Payload)

				path, err2 := filepath.Abs("Mediascape.png")
				if err2 != nil {
					log.Fatal(err)
				}

				notify = notificator.New(notificator.Options{
					DefaultIcon: path,
					AppName:     "Mediascape",
				})

				if(string(runtime.GOOS)=="linux"&&string(runtime.GOARCH)!="arm"){
					notify.Push("Mediascape", message.Payload, path)
				}else if(string(runtime.GOOS)=="linux"&&string(runtime.GOARCH)=="arm"){
					completUrl := fmt.Sprintf("http://localhost:8182/discoveragent/notification?url=%s", message.Payload)
					response, err := http.Get(completUrl)
					if err != nil {
						log.Printf("Error: %s",err)
					}else{
						defer response.Body.Close()
					}
				}
			}

			sock.broadcastBuffer <- wsBroadcast

		case "directmessage":

			messageSent := false

			// Relay message to control channel that matches target
			for _, control := range sock.controllers {
				if control.id == message.Target {
					control.send("message", message.Source, message.Target, message.Payload)
					messageSent = true
					break
				}
			}

			if !messageSent {
				fmt.Errorf("P2P message target could not be found. Not sent.")
			}

		}
	}
}

// writeConnectionPump keeps an individual websocket connection alive
func (proxy *ProxyConnection) writeConnectionPump(sock *NamedWebSocket) {
	ticker := time.NewTicker(pingPeriod)
	defer func() {
		ticker.Stop()
		proxy.removeConnection(sock)
	}()
	for {
		select {
		case <-ticker.C:
			proxy.ws.SetWriteDeadline(time.Now().Add(writeWait))
			proxy.ws.WriteMessage(websocket.PingMessage, []byte{})
		}
	}
}

// Set up a new NamedWebSocket connection instance
func (proxy *ProxyConnection) addConnection(sock *NamedWebSocket) {
	sock.proxies = append(sock.proxies, proxy)

	if proxy.writeable {
		// Inform this proxy of all the peer connections we own
		for _, peer := range sock.peers {
			proxy.send("connect", proxy.id, peer.id, "")
		}
	}

	// Start connection read/write pumps
	go proxy.writeConnectionPump(sock)
	go proxy.readConnectionPump(sock)
}

// Tear down an existing NamedWebSocket connection instance
func (proxy *ProxyConnection) removeConnection(sock *NamedWebSocket) {
	for i, conn := range sock.proxies {
		if conn.id == proxy.id {
			sock.proxies = append(sock.proxies[:i], sock.proxies[i+1:]...)
			break
		}
	}

	if proxy.writeable {
		// Inform this proxy of all the peer connections we no longer own
		for _, peer := range sock.peers {
			proxy.send("disconnect", proxy.id, peer.id, "")
		}
	}

	proxy.ws.Close()
}
<|endoftext|>


<commit_before>package colonycore

import (
	"github.com/eaciit/dbox"
	"github.com/eaciit/orm/v1"
	"github.com/eaciit/toolkit"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

type Widget struct {
	orm.ModelBase
	ID           string     `json:"_id"`
	Title        string     `json:"title"`
	DataSourceId []string   `json:"dataSourceId"`
	Description  string     `json:"description"`
	Config       toolkit.Ms `json:"config"`
	Params       toolkit.M  `json:"params"`
	URL          string     `json:"url"`
}

type DataSourceWidget struct {
	ID   string      `json:"_id"`
	Data []toolkit.M `json:"data"`
}

func (w *Widget) TableName() string {
	return "widgets"
}

func (w *Widget) RecordID() interface{} {
	return w.ID
}

func (w *Widget) Get(search string) ([]Widget, error) {
	var query *dbox.Filter

	if search != "" {
		query = dbox.Contains("_id", search)
	}

	data := []Widget{}
	cursor, err := Find(new(Widget), query)
	if err != nil {
		return nil, err
	}
	if err := cursor.Fetch(&data, 0, false); err != nil {
		return nil, err
	}
	defer cursor.Close()
	return data, nil
}

func (w *Widget) GetById() error {
	if err := Get(w, w.ID); err != nil {
		return err
	}
	return nil
}

func (w *Widget) Save() error {
	if err := Save(w); err != nil {
		return err
	}
	return nil
}

func GetPath(root string) (string, error) {
	absRoot, err := filepath.Abs(root)
	if err != nil {
		return "", err
	}
	var _path string
	var indexPath []string
	var configPath []string
	var assetPath []string
	walkFunc := func(path string, info os.FileInfo, err error) error {
		_path, filename := filepath.Split(path)
		if strings.Compare(filename, "index.html") == 0 {
			indexPath = append(indexPath, _path)
		}
		if strings.Compare(filename, "config.json") == 0 {
			configPath = append(configPath, _path)
		}

		if strings.Compare(filename, "assets") == 0 {
			assetPath = append(assetPath, _path)
		}
		return nil
	}
	if err = filepath.Walk(absRoot, walkFunc); err != nil {
		if err.Error() == "found" {
			return _path, nil
		} else {
			return "", err
		}
	}

	for _, valIndex := range indexPath {
		for _, valConfig := range configPath {
			for _, valAsset := range assetPath {
				if valIndex == valConfig && valConfig == valAsset {
					_path = valConfig
					break
				}
			}

		}
	}
	return _path, nil
}

func (w *Widget) ExtractFile(compressedSource string, fileName string) (toolkit.Ms, error) {
	compressedFile := filepath.Join(compressedSource, fileName)
	extractDest := filepath.Join(compressedSource, w.ID)

	if err := os.RemoveAll(extractDest); err != nil {
		return nil, err
	}

	if strings.Contains(fileName, ".tar.gz") {
		if err := toolkit.TarGzExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	} else if strings.Contains(fileName, ".gz") {
		if err := toolkit.GzExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	} else if strings.Contains(fileName, ".tar") {
		if err := toolkit.TarExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	} else if strings.Contains(fileName, ".zip") {
		if err := toolkit.ZipExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	}

	if err := os.Remove(compressedFile); err != nil {
		return nil, err
	}

	path, err := GetPath(extractDest)
	if err != nil {
		return nil, err
	}

	urlPath := filepath.ToSlash(path)
	splitPath := strings.SplitAfter(urlPath, "/data-root/widget/")
	w.URL = strings.Join([]string{w.URL, "res-widget", splitPath[1]}, "/")

	getConfigFile := filepath.Join(path, "config.json")
	content, err := ioutil.ReadFile(getConfigFile)
	if err != nil {
		return nil, err
	}

	result := toolkit.Ms{}
	err = toolkit.Unjson(content, &result)
	if err != nil {
		return nil, err
	}

	return result, nil
}

func (w *Widget) Delete(compressedSource string) error {
	extractDest := filepath.Join(compressedSource, w.ID)
	if err := Delete(w); err != nil {
		return err
	}

	if err := os.RemoveAll(extractDest); err != nil {
		return err
	}
	return nil
}
<commit_msg>minor update<commit_after>package colonycore

import (
	"github.com/eaciit/dbox"
	"github.com/eaciit/orm/v1"
	"github.com/eaciit/toolkit"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

type Widget struct {
	orm.ModelBase
	ID           string     `json:"_id"`
	Title        string     `json:"title"`
	DataSourceId []string   `json:"dataSourceId"`
	Description  string     `json:"description"`
	Config       toolkit.Ms `json:"config"`
	Params       toolkit.M  `json:"params"`
	URL          string     `json:"url"`
}

type DataSourceWidget struct {
	ID   string      `json:"_id"`
	Data []toolkit.M `json:"data"`
}

func (w *Widget) TableName() string {
	return "widgets"
}

func (w *Widget) RecordID() interface{} {
	return w.ID
}

func (w *Widget) Get(search string) ([]Widget, error) {
	var query *dbox.Filter

	if search != "" {
		query = dbox.Contains("_id", search)
	}

	data := []Widget{}
	cursor, err := Find(new(Widget), query)
	if err != nil {
		return nil, err
	}
	if err := cursor.Fetch(&data, 0, false); err != nil {
		return nil, err
	}
	defer cursor.Close()
	return data, nil
}

func (w *Widget) GetById() error {
	if err := Get(w, w.ID); err != nil {
		return err
	}
	return nil
}

func (w *Widget) Save() error {
	if err := Save(w); err != nil {
		return err
	}
	return nil
}

func GetPath(root string) (string, error) {
	absRoot, err := filepath.Abs(root)
	if err != nil {
		return "", err
	}
	var _path string
	var indexPath []string
	var configPath []string
	var assetPath []string
	walkFunc := func(path string, info os.FileInfo, err error) error {
		_path, filename := filepath.Split(path)
		if strings.Compare(filename, "index.html") == 0 {
			indexPath = append(indexPath, _path)
		}
		if strings.Compare(filename, "config.json") == 0 {
			configPath = append(configPath, _path)
		}

		if strings.Compare(filename, "assets") == 0 {
			assetPath = append(assetPath, _path)
		}
		return nil
	}
	if err = filepath.Walk(absRoot, walkFunc); err != nil {
		return "", err
	}

	for _, valIndex := range indexPath {
		for _, valConfig := range configPath {
			for _, valAsset := range assetPath {
				if valIndex == valConfig && valConfig == valAsset {
					_path = valConfig
					break
				}
			}

		}
	}
	return _path, nil
}

func (w *Widget) ExtractFile(compressedSource string, fileName string) (toolkit.Ms, error) {
	compressedFile := filepath.Join(compressedSource, fileName)
	extractDest := filepath.Join(compressedSource, w.ID)

	if err := os.RemoveAll(extractDest); err != nil {
		return nil, err
	}

	if strings.Contains(fileName, ".tar.gz") {
		if err := toolkit.TarGzExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	} else if strings.Contains(fileName, ".gz") {
		if err := toolkit.GzExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	} else if strings.Contains(fileName, ".tar") {
		if err := toolkit.TarExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	} else if strings.Contains(fileName, ".zip") {
		if err := toolkit.ZipExtract(compressedFile, extractDest); err != nil {
			return nil, err
		}
	}

	if err := os.Remove(compressedFile); err != nil {
		return nil, err
	}

	path, err := GetPath(extractDest)
	if err != nil {
		return nil, err
	}

	urlPath := filepath.ToSlash(path)
	splitPath := strings.SplitAfter(urlPath, "/data-root/widget/")
	w.URL = strings.Join([]string{w.URL, "res-widget", splitPath[1]}, "/")

	getConfigFile := filepath.Join(path, "config.json")
	content, err := ioutil.ReadFile(getConfigFile)
	if err != nil {
		return nil, err
	}

	result := toolkit.Ms{}
	err = toolkit.Unjson(content, &result)
	if err != nil {
		return nil, err
	}

	return result, nil
}

func (w *Widget) Delete(compressedSource string) error {
	extractDest := filepath.Join(compressedSource, w.ID)
	if err := Delete(w); err != nil {
		return err
	}

	if err := os.RemoveAll(extractDest); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
//
// A collection of tests for a file system backed by a GCS bucket, where in
// most cases we interact with the file system directly for creating and
// mofiying files (rather than through the side channel of the GCS bucket
// itself).
//
// These tests are registered by RegisterFSTests.

package fstesting

import (
	"io/ioutil"
	"math"
	"os"
	"path"
	"time"

	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

////////////////////////////////////////////////////////////////////////
// Read-write interaction
////////////////////////////////////////////////////////////////////////

type readWriteTest struct {
	fsTest
}

func (t *readWriteTest) OpenNonExistent_CreateFlagNotSet() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenExistingFile_ReadOnly() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.Open(path.Join(t.mfs.Dir(), "foo"))
	AssertEq(nil, err)

	defer func() {
		ExpectEq(nil, f.Close())
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Read its contents.
	fileContents, err := ioutil.ReadAll(f)
	AssertEq(nil, err)
	ExpectEq(contents, string(fileContents))

	// Attempt to write.
	n, err := f.Write([]byte("taco"))

	AssertEq(0, n)
	AssertNe(nil, err)
	ExpectThat(err, Error(HasSubstr("bad file descriptor")))
}

func (t *readWriteTest) OpenExistingFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenExistingFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenReadOnlyFileForWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Seek() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Stat() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Sync() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Truncate() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateEmptyDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) ReadFromWriteOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) WriteToReadOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) StatUnopenedFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) LstatUnopenedFile() {
	AssertTrue(false, "TODO")
}
<commit_msg>Added more test names.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
//
// A collection of tests for a file system backed by a GCS bucket, where in
// most cases we interact with the file system directly for creating and
// mofiying files (rather than through the side channel of the GCS bucket
// itself).
//
// These tests are registered by RegisterFSTests.

package fstesting

import (
	"io/ioutil"
	"math"
	"os"
	"path"
	"time"

	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
)

////////////////////////////////////////////////////////////////////////
// Read-write interaction
////////////////////////////////////////////////////////////////////////

type readWriteTest struct {
	fsTest
}

func (t *readWriteTest) OpenNonExistent_CreateFlagNotSet() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenNonExistent_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenExistingFile_ReadOnly() {
	// Create a file.
	const contents = "tacoburritoenchilada"
	AssertEq(
		nil,
		ioutil.WriteFile(
			path.Join(t.mfs.Dir(), "foo"),
			[]byte(contents),
			os.FileMode(0644)))

	// Open the file for reading.
	f, err := os.Open(path.Join(t.mfs.Dir(), "foo"))
	AssertEq(nil, err)

	defer func() {
		ExpectEq(nil, f.Close())
	}()

	// Check its vitals.
	ExpectEq(path.Join(t.mfs.Dir(), "foo"), f.Name())

	fi, err := f.Stat()
	ExpectEq("foo", fi.Name())
	ExpectEq(len(contents), fi.Size())
	ExpectEq(os.FileMode(0), fi.Mode() & ^os.ModePerm)
	ExpectLt(math.Abs(time.Since(fi.ModTime()).Seconds()), 10)
	ExpectFalse(fi.IsDir())

	// Read its contents.
	fileContents, err := ioutil.ReadAll(f)
	AssertEq(nil, err)
	ExpectEq(contents, string(fileContents))

	// Attempt to write.
	n, err := f.Write([]byte("taco"))

	AssertEq(0, n)
	AssertNe(nil, err)
	ExpectThat(err, Error(HasSubstr("bad file descriptor")))
}

func (t *readWriteTest) OpenExistingFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenExistingFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateExistingFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_WriteOnly() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenAlreadyOpenedFile_ReadWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenReadOnlyFileForWrite() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Seek() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Stat() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Sync() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) Truncate() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateEmptyDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) CreateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) OpenWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) TruncateWithinSubDirectory() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) ReadFromWriteOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) WriteToReadOnlyFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) StatUnopenedFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) LstatUnopenedFile() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) ListingsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) AdditionsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) RemovalsAreCached() {
	AssertTrue(false, "TODO")
}

func (t *readWriteTest) BufferedWritesFlushedOnUnmount() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


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

// Build toolchain using Go 1.4.
//
// The general strategy is to copy the source files we need into
// a new GOPATH workspace, adjust import paths appropriately,
// invoke the Go 1.4 go command to build those sources,
// and then copy the binaries back.

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"
)

// bootstrapDirs is a list of directories holding code that must be
// compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
// All directories in this list are relative to and must be below $GOROOT/src.
//
// The list has have two kinds of entries: names beginning with cmd/ with
// no other slashes, which are commands, and other paths, which are packages
// supporting the commands. Packages in the standard library can be listed
// if a newer copy needs to be substituted for the Go 1.4 copy when used
// by the command packages.
// These will be imported during bootstrap as bootstrap/name, like bootstrap/math/big.
var bootstrapDirs = []string{
	"cmd/asm",
	"cmd/asm/internal/arch",
	"cmd/asm/internal/asm",
	"cmd/asm/internal/flags",
	"cmd/asm/internal/lex",
	"cmd/cgo",
	"cmd/compile",
	"cmd/compile/internal/amd64",
	"cmd/compile/internal/arm",
	"cmd/compile/internal/arm64",
	"cmd/compile/internal/gc",
	"cmd/compile/internal/logopt",
	"cmd/compile/internal/mips",
	"cmd/compile/internal/mips64",
	"cmd/compile/internal/ppc64",
	"cmd/compile/internal/riscv64",
	"cmd/compile/internal/s390x",
	"cmd/compile/internal/ssa",
	"cmd/compile/internal/syntax",
	"cmd/compile/internal/types",
	"cmd/compile/internal/x86",
	"cmd/compile/internal/wasm",
	"cmd/internal/bio",
	"cmd/internal/gcprog",
	"cmd/internal/dwarf",
	"cmd/internal/edit",
	"cmd/internal/goobj2",
	"cmd/internal/objabi",
	"cmd/internal/obj",
	"cmd/internal/obj/arm",
	"cmd/internal/obj/arm64",
	"cmd/internal/obj/mips",
	"cmd/internal/obj/ppc64",
	"cmd/internal/obj/riscv",
	"cmd/internal/obj/s390x",
	"cmd/internal/obj/x86",
	"cmd/internal/obj/wasm",
	"cmd/internal/src",
	"cmd/internal/sys",
	"cmd/link",
	"cmd/link/internal/amd64",
	"cmd/link/internal/arm",
	"cmd/link/internal/arm64",
	"cmd/link/internal/benchmark",
	"cmd/link/internal/ld",
	"cmd/link/internal/loadelf",
	"cmd/link/internal/loader",
	"cmd/link/internal/loadmacho",
	"cmd/link/internal/loadpe",
	"cmd/link/internal/loadxcoff",
	"cmd/link/internal/mips",
	"cmd/link/internal/mips64",
	"cmd/link/internal/ppc64",
	"cmd/link/internal/riscv64",
	"cmd/link/internal/s390x",
	"cmd/link/internal/sym",
	"cmd/link/internal/x86",
	"compress/flate",
	"compress/zlib",
	"cmd/link/internal/wasm",
	"container/heap",
	"debug/dwarf",
	"debug/elf",
	"debug/macho",
	"debug/pe",
	"internal/goversion",
	"internal/race",
	"internal/unsafeheader",
	"internal/xcoff",
	"math/big",
	"math/bits",
	"sort",
}

// File prefixes that are ignored by go/build anyway, and cause
// problems with editor generated temporary files (#18931).
var ignorePrefixes = []string{
	".",
	"_",
}

// File suffixes that use build tags introduced since Go 1.4.
// These must not be copied into the bootstrap build directory.
var ignoreSuffixes = []string{
	"_arm64.s",
	"_arm64.go",
	"_wasm.s",
	"_wasm.go",
}

func bootstrapBuildTools() {
	goroot_bootstrap := os.Getenv("GOROOT_BOOTSTRAP")
	if goroot_bootstrap == "" {
		goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
	}
	xprintf("Building Go toolchain1 using %s.\n", goroot_bootstrap)

	mkzbootstrap(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))

	// Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
	// We use a subdirectory of $GOROOT/pkg because that's the
	// space within $GOROOT where we store all generated objects.
	// We could use a temporary directory outside $GOROOT instead,
	// but it is easier to debug on failure if the files are in a known location.
	workspace := pathf("%s/pkg/bootstrap", goroot)
	xremoveall(workspace)
	xatexit(func() { xremoveall(workspace) })
	base := pathf("%s/src/bootstrap", workspace)
	xmkdirall(base)

	// Copy source code into $GOROOT/pkg/bootstrap and rewrite import paths.
	writefile("module bootstrap\n", pathf("%s/%s", base, "go.mod"), 0)
	for _, dir := range bootstrapDirs {
		src := pathf("%s/src/%s", goroot, dir)
		dst := pathf("%s/%s", base, dir)
		xmkdirall(dst)
		if dir == "cmd/cgo" {
			// Write to src because we need the file both for bootstrap
			// and for later in the main build.
			mkzdefaultcc("", pathf("%s/zdefaultcc.go", src))
		}
	Dir:
		for _, name := range xreaddirfiles(src) {
			for _, pre := range ignorePrefixes {
				if strings.HasPrefix(name, pre) {
					continue Dir
				}
			}
			for _, suf := range ignoreSuffixes {
				if strings.HasSuffix(name, suf) {
					continue Dir
				}
			}
			srcFile := pathf("%s/%s", src, name)
			dstFile := pathf("%s/%s", dst, name)
			text := bootstrapRewriteFile(srcFile)
			writefile(text, dstFile, 0)
		}
	}

	// Set up environment for invoking Go 1.4 go command.
	// GOROOT points at Go 1.4 GOROOT,
	// GOPATH points at our bootstrap workspace,
	// GOBIN is empty, so that binaries are installed to GOPATH/bin,
	// and GOOS, GOHOSTOS, GOARCH, and GOHOSTOS are empty,
	// so that Go 1.4 builds whatever kind of binary it knows how to build.
	// Restore GOROOT, GOPATH, and GOBIN when done.
	// Don't bother with GOOS, GOHOSTOS, GOARCH, and GOHOSTARCH,
	// because setup will take care of those when bootstrapBuildTools returns.

	defer os.Setenv("GOROOT", os.Getenv("GOROOT"))
	os.Setenv("GOROOT", goroot_bootstrap)

	defer os.Setenv("GOPATH", os.Getenv("GOPATH"))
	os.Setenv("GOPATH", workspace)

	defer os.Setenv("GOBIN", os.Getenv("GOBIN"))
	os.Setenv("GOBIN", "")

	os.Setenv("GOOS", "")
	os.Setenv("GOHOSTOS", "")
	os.Setenv("GOARCH", "")
	os.Setenv("GOHOSTARCH", "")

	// Run Go 1.4 to build binaries. Use -gcflags=-l to disable inlining to
	// workaround bugs in Go 1.4's compiler. See discussion thread:
	// https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
	// Use the math_big_pure_go build tag to disable the assembly in math/big
	// which may contain unsupported instructions.
	// Note that if we are using Go 1.10 or later as bootstrap, the -gcflags=-l
	// only applies to the final cmd/go binary, but that's OK: if this is Go 1.10
	// or later we don't need to disable inlining to work around bugs in the Go 1.4 compiler.
	cmd := []string{
		pathf("%s/bin/go", goroot_bootstrap),
		"install",
		"-gcflags=-l",
		"-tags=math_big_pure_go compiler_bootstrap",
	}
	if vflag > 0 {
		cmd = append(cmd, "-v")
	}
	if tool := os.Getenv("GOBOOTSTRAP_TOOLEXEC"); tool != "" {
		cmd = append(cmd, "-toolexec="+tool)
	}
	cmd = append(cmd, "bootstrap/cmd/...")
	run(base, ShowOutput|CheckExit, cmd...)

	// Copy binaries into tool binary directory.
	for _, name := range bootstrapDirs {
		if !strings.HasPrefix(name, "cmd/") {
			continue
		}
		name = name[len("cmd/"):]
		if !strings.Contains(name, "/") {
			copyfile(pathf("%s/%s%s", tooldir, name, exe), pathf("%s/bin/%s%s", workspace, name, exe), writeExec)
		}
	}

	if vflag > 0 {
		xprintf("\n")
	}
}

var ssaRewriteFileSubstring = filepath.FromSlash("src/cmd/compile/internal/ssa/rewrite")

// isUnneededSSARewriteFile reports whether srcFile is a
// src/cmd/compile/internal/ssa/rewriteARCHNAME.go file for an
// architecture that isn't for the current runtime.GOARCH.
//
// When unneeded is true archCaps is the rewrite base filename without
// the "rewrite" prefix or ".go" suffix: AMD64, 386, ARM, ARM64, etc.
func isUnneededSSARewriteFile(srcFile string) (archCaps string, unneeded bool) {
	if !strings.Contains(srcFile, ssaRewriteFileSubstring) {
		return "", false
	}
	fileArch := strings.TrimSuffix(strings.TrimPrefix(filepath.Base(srcFile), "rewrite"), ".go")
	if fileArch == "" {
		return "", false
	}
	b := fileArch[0]
	if b == '_' || ('a' <= b && b <= 'z') {
		return "", false
	}
	archCaps = fileArch
	fileArch = strings.ToLower(fileArch)
	fileArch = strings.TrimSuffix(fileArch, "splitload")
	if fileArch == os.Getenv("GOHOSTARCH") {
		return "", false
	}
	if fileArch == strings.TrimSuffix(runtime.GOARCH, "le") {
		return "", false
	}
	if fileArch == strings.TrimSuffix(os.Getenv("GOARCH"), "le") {
		return "", false
	}
	return archCaps, true
}

func bootstrapRewriteFile(srcFile string) string {
	// During bootstrap, generate dummy rewrite files for
	// irrelevant architectures. We only need to build a bootstrap
	// binary that works for the current runtime.GOARCH.
	// This saves 6+ seconds of bootstrap.
	if archCaps, ok := isUnneededSSARewriteFile(srcFile); ok {
		return fmt.Sprintf(`// Code generated by go tool dist; DO NOT EDIT.

package ssa

func rewriteValue%s(v *Value) bool { panic("unused during bootstrap") }
func rewriteBlock%s(b *Block) bool { panic("unused during bootstrap") }
`, archCaps, archCaps)
	}

	return bootstrapFixImports(srcFile)
}

func bootstrapFixImports(srcFile string) string {
	lines := strings.SplitAfter(readfile(srcFile), "\n")
	inBlock := false
	for i, line := range lines {
		if strings.HasPrefix(line, "import (") {
			inBlock = true
			continue
		}
		if inBlock && strings.HasPrefix(line, ")") {
			inBlock = false
			continue
		}
		if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
			inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
			line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
			for _, dir := range bootstrapDirs {
				if strings.HasPrefix(dir, "cmd/") {
					continue
				}
				line = strings.Replace(line, `"`+dir+`"`, `"bootstrap/`+dir+`"`, -1)
			}
			lines[i] = line
		}
	}

	lines[0] = "// Code generated by go tool dist; DO NOT EDIT.\n// This is a bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]

	return strings.Join(lines, "")
}
<commit_msg>cmd/dist: don't copy riscv64 specific files for bootstrap build<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Build toolchain using Go 1.4.
//
// The general strategy is to copy the source files we need into
// a new GOPATH workspace, adjust import paths appropriately,
// invoke the Go 1.4 go command to build those sources,
// and then copy the binaries back.

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"
)

// bootstrapDirs is a list of directories holding code that must be
// compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
// All directories in this list are relative to and must be below $GOROOT/src.
//
// The list has have two kinds of entries: names beginning with cmd/ with
// no other slashes, which are commands, and other paths, which are packages
// supporting the commands. Packages in the standard library can be listed
// if a newer copy needs to be substituted for the Go 1.4 copy when used
// by the command packages.
// These will be imported during bootstrap as bootstrap/name, like bootstrap/math/big.
var bootstrapDirs = []string{
	"cmd/asm",
	"cmd/asm/internal/arch",
	"cmd/asm/internal/asm",
	"cmd/asm/internal/flags",
	"cmd/asm/internal/lex",
	"cmd/cgo",
	"cmd/compile",
	"cmd/compile/internal/amd64",
	"cmd/compile/internal/arm",
	"cmd/compile/internal/arm64",
	"cmd/compile/internal/gc",
	"cmd/compile/internal/logopt",
	"cmd/compile/internal/mips",
	"cmd/compile/internal/mips64",
	"cmd/compile/internal/ppc64",
	"cmd/compile/internal/riscv64",
	"cmd/compile/internal/s390x",
	"cmd/compile/internal/ssa",
	"cmd/compile/internal/syntax",
	"cmd/compile/internal/types",
	"cmd/compile/internal/x86",
	"cmd/compile/internal/wasm",
	"cmd/internal/bio",
	"cmd/internal/gcprog",
	"cmd/internal/dwarf",
	"cmd/internal/edit",
	"cmd/internal/goobj2",
	"cmd/internal/objabi",
	"cmd/internal/obj",
	"cmd/internal/obj/arm",
	"cmd/internal/obj/arm64",
	"cmd/internal/obj/mips",
	"cmd/internal/obj/ppc64",
	"cmd/internal/obj/riscv",
	"cmd/internal/obj/s390x",
	"cmd/internal/obj/x86",
	"cmd/internal/obj/wasm",
	"cmd/internal/src",
	"cmd/internal/sys",
	"cmd/link",
	"cmd/link/internal/amd64",
	"cmd/link/internal/arm",
	"cmd/link/internal/arm64",
	"cmd/link/internal/benchmark",
	"cmd/link/internal/ld",
	"cmd/link/internal/loadelf",
	"cmd/link/internal/loader",
	"cmd/link/internal/loadmacho",
	"cmd/link/internal/loadpe",
	"cmd/link/internal/loadxcoff",
	"cmd/link/internal/mips",
	"cmd/link/internal/mips64",
	"cmd/link/internal/ppc64",
	"cmd/link/internal/riscv64",
	"cmd/link/internal/s390x",
	"cmd/link/internal/sym",
	"cmd/link/internal/x86",
	"compress/flate",
	"compress/zlib",
	"cmd/link/internal/wasm",
	"container/heap",
	"debug/dwarf",
	"debug/elf",
	"debug/macho",
	"debug/pe",
	"internal/goversion",
	"internal/race",
	"internal/unsafeheader",
	"internal/xcoff",
	"math/big",
	"math/bits",
	"sort",
}

// File prefixes that are ignored by go/build anyway, and cause
// problems with editor generated temporary files (#18931).
var ignorePrefixes = []string{
	".",
	"_",
}

// File suffixes that use build tags introduced since Go 1.4.
// These must not be copied into the bootstrap build directory.
var ignoreSuffixes = []string{
	"_arm64.s",
	"_arm64.go",
	"_riscv64.s",
	"_riscv64.go",
	"_wasm.s",
	"_wasm.go",
}

func bootstrapBuildTools() {
	goroot_bootstrap := os.Getenv("GOROOT_BOOTSTRAP")
	if goroot_bootstrap == "" {
		goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
	}
	xprintf("Building Go toolchain1 using %s.\n", goroot_bootstrap)

	mkzbootstrap(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))

	// Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
	// We use a subdirectory of $GOROOT/pkg because that's the
	// space within $GOROOT where we store all generated objects.
	// We could use a temporary directory outside $GOROOT instead,
	// but it is easier to debug on failure if the files are in a known location.
	workspace := pathf("%s/pkg/bootstrap", goroot)
	xremoveall(workspace)
	xatexit(func() { xremoveall(workspace) })
	base := pathf("%s/src/bootstrap", workspace)
	xmkdirall(base)

	// Copy source code into $GOROOT/pkg/bootstrap and rewrite import paths.
	writefile("module bootstrap\n", pathf("%s/%s", base, "go.mod"), 0)
	for _, dir := range bootstrapDirs {
		src := pathf("%s/src/%s", goroot, dir)
		dst := pathf("%s/%s", base, dir)
		xmkdirall(dst)
		if dir == "cmd/cgo" {
			// Write to src because we need the file both for bootstrap
			// and for later in the main build.
			mkzdefaultcc("", pathf("%s/zdefaultcc.go", src))
		}
	Dir:
		for _, name := range xreaddirfiles(src) {
			for _, pre := range ignorePrefixes {
				if strings.HasPrefix(name, pre) {
					continue Dir
				}
			}
			for _, suf := range ignoreSuffixes {
				if strings.HasSuffix(name, suf) {
					continue Dir
				}
			}
			srcFile := pathf("%s/%s", src, name)
			dstFile := pathf("%s/%s", dst, name)
			text := bootstrapRewriteFile(srcFile)
			writefile(text, dstFile, 0)
		}
	}

	// Set up environment for invoking Go 1.4 go command.
	// GOROOT points at Go 1.4 GOROOT,
	// GOPATH points at our bootstrap workspace,
	// GOBIN is empty, so that binaries are installed to GOPATH/bin,
	// and GOOS, GOHOSTOS, GOARCH, and GOHOSTOS are empty,
	// so that Go 1.4 builds whatever kind of binary it knows how to build.
	// Restore GOROOT, GOPATH, and GOBIN when done.
	// Don't bother with GOOS, GOHOSTOS, GOARCH, and GOHOSTARCH,
	// because setup will take care of those when bootstrapBuildTools returns.

	defer os.Setenv("GOROOT", os.Getenv("GOROOT"))
	os.Setenv("GOROOT", goroot_bootstrap)

	defer os.Setenv("GOPATH", os.Getenv("GOPATH"))
	os.Setenv("GOPATH", workspace)

	defer os.Setenv("GOBIN", os.Getenv("GOBIN"))
	os.Setenv("GOBIN", "")

	os.Setenv("GOOS", "")
	os.Setenv("GOHOSTOS", "")
	os.Setenv("GOARCH", "")
	os.Setenv("GOHOSTARCH", "")

	// Run Go 1.4 to build binaries. Use -gcflags=-l to disable inlining to
	// workaround bugs in Go 1.4's compiler. See discussion thread:
	// https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
	// Use the math_big_pure_go build tag to disable the assembly in math/big
	// which may contain unsupported instructions.
	// Note that if we are using Go 1.10 or later as bootstrap, the -gcflags=-l
	// only applies to the final cmd/go binary, but that's OK: if this is Go 1.10
	// or later we don't need to disable inlining to work around bugs in the Go 1.4 compiler.
	cmd := []string{
		pathf("%s/bin/go", goroot_bootstrap),
		"install",
		"-gcflags=-l",
		"-tags=math_big_pure_go compiler_bootstrap",
	}
	if vflag > 0 {
		cmd = append(cmd, "-v")
	}
	if tool := os.Getenv("GOBOOTSTRAP_TOOLEXEC"); tool != "" {
		cmd = append(cmd, "-toolexec="+tool)
	}
	cmd = append(cmd, "bootstrap/cmd/...")
	run(base, ShowOutput|CheckExit, cmd...)

	// Copy binaries into tool binary directory.
	for _, name := range bootstrapDirs {
		if !strings.HasPrefix(name, "cmd/") {
			continue
		}
		name = name[len("cmd/"):]
		if !strings.Contains(name, "/") {
			copyfile(pathf("%s/%s%s", tooldir, name, exe), pathf("%s/bin/%s%s", workspace, name, exe), writeExec)
		}
	}

	if vflag > 0 {
		xprintf("\n")
	}
}

var ssaRewriteFileSubstring = filepath.FromSlash("src/cmd/compile/internal/ssa/rewrite")

// isUnneededSSARewriteFile reports whether srcFile is a
// src/cmd/compile/internal/ssa/rewriteARCHNAME.go file for an
// architecture that isn't for the current runtime.GOARCH.
//
// When unneeded is true archCaps is the rewrite base filename without
// the "rewrite" prefix or ".go" suffix: AMD64, 386, ARM, ARM64, etc.
func isUnneededSSARewriteFile(srcFile string) (archCaps string, unneeded bool) {
	if !strings.Contains(srcFile, ssaRewriteFileSubstring) {
		return "", false
	}
	fileArch := strings.TrimSuffix(strings.TrimPrefix(filepath.Base(srcFile), "rewrite"), ".go")
	if fileArch == "" {
		return "", false
	}
	b := fileArch[0]
	if b == '_' || ('a' <= b && b <= 'z') {
		return "", false
	}
	archCaps = fileArch
	fileArch = strings.ToLower(fileArch)
	fileArch = strings.TrimSuffix(fileArch, "splitload")
	if fileArch == os.Getenv("GOHOSTARCH") {
		return "", false
	}
	if fileArch == strings.TrimSuffix(runtime.GOARCH, "le") {
		return "", false
	}
	if fileArch == strings.TrimSuffix(os.Getenv("GOARCH"), "le") {
		return "", false
	}
	return archCaps, true
}

func bootstrapRewriteFile(srcFile string) string {
	// During bootstrap, generate dummy rewrite files for
	// irrelevant architectures. We only need to build a bootstrap
	// binary that works for the current runtime.GOARCH.
	// This saves 6+ seconds of bootstrap.
	if archCaps, ok := isUnneededSSARewriteFile(srcFile); ok {
		return fmt.Sprintf(`// Code generated by go tool dist; DO NOT EDIT.

package ssa

func rewriteValue%s(v *Value) bool { panic("unused during bootstrap") }
func rewriteBlock%s(b *Block) bool { panic("unused during bootstrap") }
`, archCaps, archCaps)
	}

	return bootstrapFixImports(srcFile)
}

func bootstrapFixImports(srcFile string) string {
	lines := strings.SplitAfter(readfile(srcFile), "\n")
	inBlock := false
	for i, line := range lines {
		if strings.HasPrefix(line, "import (") {
			inBlock = true
			continue
		}
		if inBlock && strings.HasPrefix(line, ")") {
			inBlock = false
			continue
		}
		if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
			inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
			line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
			for _, dir := range bootstrapDirs {
				if strings.HasPrefix(dir, "cmd/") {
					continue
				}
				line = strings.Replace(line, `"`+dir+`"`, `"bootstrap/`+dir+`"`, -1)
			}
			lines[i] = line
		}
	}

	lines[0] = "// Code generated by go tool dist; DO NOT EDIT.\n// This is a bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]

	return strings.Join(lines, "")
}
<|endoftext|>


<commit_before>// Copyright 2014 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 main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"testing"
	"time"
	"unicode/utf8"
)

func TestExactly16Bytes(t *testing.T) {
	var tests = []string{
		"",
		"a",
		"日本語",
		"1234567890123456",
		"12345678901234567890",
		"1234567890123本語4567890",
		"12345678901234日本語567890",
		"123456789012345日本語67890",
		"1234567890123456日本語7890",
		"1234567890123456日本語7日本語890",
	}
	for _, str := range tests {
		got := exactly16Bytes(str)
		if len(got) != 16 {
			t.Errorf("exactly16Bytes(%q) is %q, length %d", str, got, len(got))
		}
		// Make sure it is full runes.
		for _, c := range got {
			if c == utf8.RuneError {
				t.Errorf("exactly16Bytes(%q) is %q, has partial rune", str, got)
			}
		}
	}
}

// tmpDir creates a temporary directory and returns its name.
func tmpDir(t *testing.T) string {
	name, err := ioutil.TempDir("", "pack")
	if err != nil {
		t.Fatal(err)
	}
	return name
}

// testCreate creates an archive in the specified directory.
func testCreate(t *testing.T, dir string) {
	name := filepath.Join(dir, "pack.a")
	ar := archive(name, os.O_RDWR, nil)
	// Add an entry by hand.
	ar.addFile(helloFile.Reset())
	ar.fd.Close()
	// Now check it.
	ar = archive(name, os.O_RDONLY, []string{helloFile.name})
	var buf bytes.Buffer
	stdout = &buf
	verbose = true
	defer func() {
		stdout = os.Stdout
		verbose = false
	}()
	ar.scan(ar.printContents)
	ar.fd.Close()
	result := buf.String()
	// Expect verbose output plus file contents.
	expect := fmt.Sprintf("%s\n%s", helloFile.name, helloFile.contents)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that we can create an archive, write to it, and get the same contents back.
// Tests the rv and then the pv command on a new archive.
func TestCreate(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	testCreate(t, dir)
}

// Test that we can create an archive twice with the same name (Issue 8369).
func TestCreateTwice(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	testCreate(t, dir)
	testCreate(t, dir)
}

// Test that we can create an archive, put some files in it, and get back a correct listing.
// Tests the tv command.
func TestTableOfContents(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	name := filepath.Join(dir, "pack.a")
	ar := archive(name, os.O_RDWR, nil)

	// Add some entries by hand.
	ar.addFile(helloFile.Reset())
	ar.addFile(goodbyeFile.Reset())
	ar.fd.Close()

	// Now print it.
	ar = archive(name, os.O_RDONLY, nil)
	var buf bytes.Buffer
	stdout = &buf
	verbose = true
	defer func() {
		stdout = os.Stdout
		verbose = false
	}()
	ar.scan(ar.tableOfContents)
	ar.fd.Close()
	result := buf.String()
	// Expect verbose listing.
	expect := fmt.Sprintf("%s\n%s\n", helloFile.Entry(), goodbyeFile.Entry())
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}

	// Do it again without verbose.
	verbose = false
	buf.Reset()
	ar = archive(name, os.O_RDONLY, nil)
	ar.scan(ar.tableOfContents)
	ar.fd.Close()
	result = buf.String()
	// Expect non-verbose listing.
	expect = fmt.Sprintf("%s\n%s\n", helloFile.name, goodbyeFile.name)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}

	// Do it again with file list arguments.
	verbose = false
	buf.Reset()
	ar = archive(name, os.O_RDONLY, []string{helloFile.name})
	ar.scan(ar.tableOfContents)
	ar.fd.Close()
	result = buf.String()
	// Expect only helloFile.
	expect = fmt.Sprintf("%s\n", helloFile.name)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that we can create an archive, put some files in it, and get back a file.
// Tests the x command.
func TestExtract(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	name := filepath.Join(dir, "pack.a")
	ar := archive(name, os.O_RDWR, nil)
	// Add some entries by hand.
	ar.addFile(helloFile.Reset())
	ar.addFile(goodbyeFile.Reset())
	ar.fd.Close()
	// Now extract one file. We chdir to the directory of the archive for simplicity.
	pwd, err := os.Getwd()
	if err != nil {
		t.Fatal("os.Getwd: ", err)
	}
	err = os.Chdir(dir)
	if err != nil {
		t.Fatal("os.Chdir: ", err)
	}
	defer func() {
		err := os.Chdir(pwd)
		if err != nil {
			t.Fatal("os.Chdir: ", err)
		}
	}()
	ar = archive(name, os.O_RDONLY, []string{goodbyeFile.name})
	ar.scan(ar.extractContents)
	ar.fd.Close()
	data, err := ioutil.ReadFile(goodbyeFile.name)
	if err != nil {
		t.Fatal(err)
	}
	// Expect contents of file.
	result := string(data)
	expect := goodbyeFile.contents
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that pack-created archives can be understood by the tools.
func TestHello(t *testing.T) {
	switch runtime.GOOS {
	case "android", "nacl":
		t.Skipf("skipping on %s", runtime.GOOS)
	}

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	hello := filepath.Join(dir, "hello.go")
	prog := `
		package main
		func main() {
			println("hello world")
		}
	`
	err := ioutil.WriteFile(hello, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	char := findChar(t, dir)

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	run("go", "build", "cmd/pack") // writes pack binary to dir
	run("go", "tool", char+"g", "hello.go")
	run("./pack", "grc", "hello.a", "hello."+char)
	run("go", "tool", char+"l", "-o", "a.out", "hello.a")
	out := run("./a.out")
	if out != "hello world\n" {
		t.Fatalf("incorrect output: %q, want %q", out, "hello world\n")
	}
}

// Test that pack works with very long lines in PKGDEF.
func TestLargeDefs(t *testing.T) {
	switch runtime.GOOS {
	case "android", "nacl":
		t.Skipf("skipping on %s", runtime.GOOS)
	}

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	large := filepath.Join(dir, "large.go")
	f, err := os.Create(large)
	if err != nil {
		t.Fatal(err)
	}
	b := bufio.NewWriter(f)

	printf := func(format string, args ...interface{}) {
		_, err := fmt.Fprintf(b, format, args...)
		if err != nil {
			t.Fatalf("Writing to %s: %v", large, err)
		}
	}

	printf("package large\n\ntype T struct {\n")
	for i := 0; i < 10000; i++ {
		printf("f%d int `tag:\"", i)
		for j := 0; j < 100; j++ {
			printf("t%d=%d,", j, j)
		}
		printf("\"`\n")
	}
	printf("}\n")
	if err = b.Flush(); err != nil {
		t.Fatal(err)
	}
	if err = f.Close(); err != nil {
		t.Fatal(err)
	}

	main := filepath.Join(dir, "main.go")
	prog := `
		package main
		import "large"
		var V large.T
		func main() {
			println("ok")
		}
	`
	err = ioutil.WriteFile(main, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	char := findChar(t, dir)

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	run("go", "build", "cmd/pack") // writes pack binary to dir
	run("go", "tool", char+"g", "large.go")
	run("./pack", "grc", "large.a", "large."+char)
	run("go", "tool", char+"g", "-I", ".", "main.go")
	run("go", "tool", char+"l", "-L", ".", "-o", "a.out", "main."+char)
	out := run("./a.out")
	if out != "ok\n" {
		t.Fatalf("incorrect output: %q, want %q", out, "ok\n")
	}
}

// doRun runs a program in a directory and returns the output.
func doRun(t *testing.T, dir string, args ...string) string {
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Dir = dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("%v: %v\n%s", args, err, string(out))
	}
	return string(out)
}

// findChar returns the architecture character for the go command.
func findChar(t *testing.T, dir string) string {
	out := doRun(t, dir, "go", "env")
	re, err := regexp.Compile(`\s*GOCHAR=['"]?(\w)['"]?`)
	if err != nil {
		t.Fatal(err)
	}
	fields := re.FindStringSubmatch(out)
	if fields == nil {
		t.Fatal("cannot find GOCHAR in 'go env' output:\n", out)
	}
	return fields[1]
}

// Fake implementation of files.

var helloFile = &FakeFile{
	name:     "hello",
	contents: "hello world", // 11 bytes, an odd number.
	mode:     0644,
}

var goodbyeFile = &FakeFile{
	name:     "goodbye",
	contents: "Sayonara, Jim", // 13 bytes, another odd number.
	mode:     0644,
}

// FakeFile implements FileLike and also os.FileInfo.
type FakeFile struct {
	name     string
	contents string
	mode     os.FileMode
	offset   int
}

// Reset prepares a FakeFile for reuse.
func (f *FakeFile) Reset() *FakeFile {
	f.offset = 0
	return f
}

// FileLike methods.

func (f *FakeFile) Name() string {
	// A bit of a cheat: we only have a basename, so that's also ok for FileInfo.
	return f.name
}

func (f *FakeFile) Stat() (os.FileInfo, error) {
	return f, nil
}

func (f *FakeFile) Read(p []byte) (int, error) {
	if f.offset >= len(f.contents) {
		return 0, io.EOF
	}
	n := copy(p, f.contents[f.offset:])
	f.offset += n
	return n, nil
}

func (f *FakeFile) Close() error {
	return nil
}

// os.FileInfo methods.

func (f *FakeFile) Size() int64 {
	return int64(len(f.contents))
}

func (f *FakeFile) Mode() os.FileMode {
	return f.mode
}

func (f *FakeFile) ModTime() time.Time {
	return time.Time{}
}

func (f *FakeFile) IsDir() bool {
	return false
}

func (f *FakeFile) Sys() interface{} {
	return nil
}

// Special helpers.

func (f *FakeFile) Entry() *Entry {
	return &Entry{
		name:  f.name,
		mtime: 0, // Defined to be zero.
		uid:   0, // Ditto.
		gid:   0, // Ditto.
		mode:  f.mode,
		size:  int64(len(f.contents)),
	}
}
<commit_msg>cmd/pack: make a test less disk-intensive in short mode<commit_after>// Copyright 2014 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 main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"testing"
	"time"
	"unicode/utf8"
)

func TestExactly16Bytes(t *testing.T) {
	var tests = []string{
		"",
		"a",
		"日本語",
		"1234567890123456",
		"12345678901234567890",
		"1234567890123本語4567890",
		"12345678901234日本語567890",
		"123456789012345日本語67890",
		"1234567890123456日本語7890",
		"1234567890123456日本語7日本語890",
	}
	for _, str := range tests {
		got := exactly16Bytes(str)
		if len(got) != 16 {
			t.Errorf("exactly16Bytes(%q) is %q, length %d", str, got, len(got))
		}
		// Make sure it is full runes.
		for _, c := range got {
			if c == utf8.RuneError {
				t.Errorf("exactly16Bytes(%q) is %q, has partial rune", str, got)
			}
		}
	}
}

// tmpDir creates a temporary directory and returns its name.
func tmpDir(t *testing.T) string {
	name, err := ioutil.TempDir("", "pack")
	if err != nil {
		t.Fatal(err)
	}
	return name
}

// testCreate creates an archive in the specified directory.
func testCreate(t *testing.T, dir string) {
	name := filepath.Join(dir, "pack.a")
	ar := archive(name, os.O_RDWR, nil)
	// Add an entry by hand.
	ar.addFile(helloFile.Reset())
	ar.fd.Close()
	// Now check it.
	ar = archive(name, os.O_RDONLY, []string{helloFile.name})
	var buf bytes.Buffer
	stdout = &buf
	verbose = true
	defer func() {
		stdout = os.Stdout
		verbose = false
	}()
	ar.scan(ar.printContents)
	ar.fd.Close()
	result := buf.String()
	// Expect verbose output plus file contents.
	expect := fmt.Sprintf("%s\n%s", helloFile.name, helloFile.contents)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that we can create an archive, write to it, and get the same contents back.
// Tests the rv and then the pv command on a new archive.
func TestCreate(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	testCreate(t, dir)
}

// Test that we can create an archive twice with the same name (Issue 8369).
func TestCreateTwice(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	testCreate(t, dir)
	testCreate(t, dir)
}

// Test that we can create an archive, put some files in it, and get back a correct listing.
// Tests the tv command.
func TestTableOfContents(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	name := filepath.Join(dir, "pack.a")
	ar := archive(name, os.O_RDWR, nil)

	// Add some entries by hand.
	ar.addFile(helloFile.Reset())
	ar.addFile(goodbyeFile.Reset())
	ar.fd.Close()

	// Now print it.
	ar = archive(name, os.O_RDONLY, nil)
	var buf bytes.Buffer
	stdout = &buf
	verbose = true
	defer func() {
		stdout = os.Stdout
		verbose = false
	}()
	ar.scan(ar.tableOfContents)
	ar.fd.Close()
	result := buf.String()
	// Expect verbose listing.
	expect := fmt.Sprintf("%s\n%s\n", helloFile.Entry(), goodbyeFile.Entry())
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}

	// Do it again without verbose.
	verbose = false
	buf.Reset()
	ar = archive(name, os.O_RDONLY, nil)
	ar.scan(ar.tableOfContents)
	ar.fd.Close()
	result = buf.String()
	// Expect non-verbose listing.
	expect = fmt.Sprintf("%s\n%s\n", helloFile.name, goodbyeFile.name)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}

	// Do it again with file list arguments.
	verbose = false
	buf.Reset()
	ar = archive(name, os.O_RDONLY, []string{helloFile.name})
	ar.scan(ar.tableOfContents)
	ar.fd.Close()
	result = buf.String()
	// Expect only helloFile.
	expect = fmt.Sprintf("%s\n", helloFile.name)
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that we can create an archive, put some files in it, and get back a file.
// Tests the x command.
func TestExtract(t *testing.T) {
	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	name := filepath.Join(dir, "pack.a")
	ar := archive(name, os.O_RDWR, nil)
	// Add some entries by hand.
	ar.addFile(helloFile.Reset())
	ar.addFile(goodbyeFile.Reset())
	ar.fd.Close()
	// Now extract one file. We chdir to the directory of the archive for simplicity.
	pwd, err := os.Getwd()
	if err != nil {
		t.Fatal("os.Getwd: ", err)
	}
	err = os.Chdir(dir)
	if err != nil {
		t.Fatal("os.Chdir: ", err)
	}
	defer func() {
		err := os.Chdir(pwd)
		if err != nil {
			t.Fatal("os.Chdir: ", err)
		}
	}()
	ar = archive(name, os.O_RDONLY, []string{goodbyeFile.name})
	ar.scan(ar.extractContents)
	ar.fd.Close()
	data, err := ioutil.ReadFile(goodbyeFile.name)
	if err != nil {
		t.Fatal(err)
	}
	// Expect contents of file.
	result := string(data)
	expect := goodbyeFile.contents
	if result != expect {
		t.Fatalf("expected %q got %q", expect, result)
	}
}

// Test that pack-created archives can be understood by the tools.
func TestHello(t *testing.T) {
	switch runtime.GOOS {
	case "android", "nacl":
		t.Skipf("skipping on %s", runtime.GOOS)
	}

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	hello := filepath.Join(dir, "hello.go")
	prog := `
		package main
		func main() {
			println("hello world")
		}
	`
	err := ioutil.WriteFile(hello, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	char := findChar(t, dir)

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	run("go", "build", "cmd/pack") // writes pack binary to dir
	run("go", "tool", char+"g", "hello.go")
	run("./pack", "grc", "hello.a", "hello."+char)
	run("go", "tool", char+"l", "-o", "a.out", "hello.a")
	out := run("./a.out")
	if out != "hello world\n" {
		t.Fatalf("incorrect output: %q, want %q", out, "hello world\n")
	}
}

// Test that pack works with very long lines in PKGDEF.
func TestLargeDefs(t *testing.T) {
	switch runtime.GOOS {
	case "android", "nacl":
		t.Skipf("skipping on %s", runtime.GOOS)
	}

	dir := tmpDir(t)
	defer os.RemoveAll(dir)
	large := filepath.Join(dir, "large.go")
	f, err := os.Create(large)
	if err != nil {
		t.Fatal(err)
	}
	b := bufio.NewWriter(f)

	printf := func(format string, args ...interface{}) {
		_, err := fmt.Fprintf(b, format, args...)
		if err != nil {
			t.Fatalf("Writing to %s: %v", large, err)
		}
	}

	n := 10000
	if testing.Short() {
		// Issue 9656: 10,000 is too aggressive for several
		// builders, with ~120 MB of disk consumed. 1,000 is
		// still enough to exercise the old bug.
		n = 1000
	}
	printf("package large\n\ntype T struct {\n")
	for i := 0; i < n; i++ {
		printf("f%d int `tag:\"", i)
		for j := 0; j < 100; j++ {
			printf("t%d=%d,", j, j)
		}
		printf("\"`\n")
	}
	printf("}\n")
	if err = b.Flush(); err != nil {
		t.Fatal(err)
	}
	if err = f.Close(); err != nil {
		t.Fatal(err)
	}

	main := filepath.Join(dir, "main.go")
	prog := `
		package main
		import "large"
		var V large.T
		func main() {
			println("ok")
		}
	`
	err = ioutil.WriteFile(main, []byte(prog), 0666)
	if err != nil {
		t.Fatal(err)
	}

	char := findChar(t, dir)

	run := func(args ...string) string {
		return doRun(t, dir, args...)
	}

	run("go", "build", "cmd/pack") // writes pack binary to dir
	run("go", "tool", char+"g", "large.go")
	run("./pack", "grc", "large.a", "large."+char)
	run("go", "tool", char+"g", "-I", ".", "main.go")
	run("go", "tool", char+"l", "-L", ".", "-o", "a.out", "main."+char)
	out := run("./a.out")
	if out != "ok\n" {
		t.Fatalf("incorrect output: %q, want %q", out, "ok\n")
	}
}

// doRun runs a program in a directory and returns the output.
func doRun(t *testing.T, dir string, args ...string) string {
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Dir = dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("%v: %v\n%s", args, err, string(out))
	}
	return string(out)
}

// findChar returns the architecture character for the go command.
func findChar(t *testing.T, dir string) string {
	out := doRun(t, dir, "go", "env")
	re, err := regexp.Compile(`\s*GOCHAR=['"]?(\w)['"]?`)
	if err != nil {
		t.Fatal(err)
	}
	fields := re.FindStringSubmatch(out)
	if fields == nil {
		t.Fatal("cannot find GOCHAR in 'go env' output:\n", out)
	}
	return fields[1]
}

// Fake implementation of files.

var helloFile = &FakeFile{
	name:     "hello",
	contents: "hello world", // 11 bytes, an odd number.
	mode:     0644,
}

var goodbyeFile = &FakeFile{
	name:     "goodbye",
	contents: "Sayonara, Jim", // 13 bytes, another odd number.
	mode:     0644,
}

// FakeFile implements FileLike and also os.FileInfo.
type FakeFile struct {
	name     string
	contents string
	mode     os.FileMode
	offset   int
}

// Reset prepares a FakeFile for reuse.
func (f *FakeFile) Reset() *FakeFile {
	f.offset = 0
	return f
}

// FileLike methods.

func (f *FakeFile) Name() string {
	// A bit of a cheat: we only have a basename, so that's also ok for FileInfo.
	return f.name
}

func (f *FakeFile) Stat() (os.FileInfo, error) {
	return f, nil
}

func (f *FakeFile) Read(p []byte) (int, error) {
	if f.offset >= len(f.contents) {
		return 0, io.EOF
	}
	n := copy(p, f.contents[f.offset:])
	f.offset += n
	return n, nil
}

func (f *FakeFile) Close() error {
	return nil
}

// os.FileInfo methods.

func (f *FakeFile) Size() int64 {
	return int64(len(f.contents))
}

func (f *FakeFile) Mode() os.FileMode {
	return f.mode
}

func (f *FakeFile) ModTime() time.Time {
	return time.Time{}
}

func (f *FakeFile) IsDir() bool {
	return false
}

func (f *FakeFile) Sys() interface{} {
	return nil
}

// Special helpers.

func (f *FakeFile) Entry() *Entry {
	return &Entry{
		name:  f.name,
		mtime: 0, // Defined to be zero.
		uid:   0, // Ditto.
		gid:   0, // Ditto.
		mode:  f.mode,
		size:  int64(len(f.contents)),
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package test

import (
	"fmt"

	"github.com/golang/mock/gomock"
	"github.com/google/go-cmp/cmp"
)

// CmpMatcher returns a new matcher backed by go-cmp/cmp.Equal.
func CmpMatcher(x interface{}) gomock.Matcher {
	return &matcher{x}
}

type matcher struct {
	expected interface{}
}

func (m matcher) Matches(x interface{}) bool {
	return cmp.Equal(m.expected, x)
}

func (m matcher) String() string {
	return fmt.Sprintf("%v", m.expected)
}
<commit_msg>Wire up Cmp Options (#198)<commit_after>// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package test

import (
	"fmt"

	"github.com/golang/mock/gomock"
	"github.com/google/go-cmp/cmp"
)

// CmpMatcher returns a new matcher backed by go-cmp/cmp.Equal.
func CmpMatcher(x interface{}, opts ...cmp.Option) gomock.Matcher {
	return &matcher{x, opts}
}

type matcher struct {
	expected interface{}
	opts     cmp.Options
}

func (m matcher) Matches(x interface{}) bool {
	return cmp.Equal(m.expected, x, m.opts...)
}

func (m matcher) String() string {
	return fmt.Sprintf("%v", m.expected)
}
<|endoftext|>


<commit_before>// run

// Copyright 2017 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.

// Test forms of method expressions T.m where T is
// a literal type.

package main

var got, want string

type I interface {
	m()
}

type S struct {
}

func (S) m()          { got += " m()" }
func (S) m1(s string) { got += " m1(" + s + ")" }

type T int

func (T) m2() { got += " m2()" }

func main() {
	// method expressions with named receiver types
	I.m(S{})
	want += " m()"

	S.m1(S{}, "a")
	want += " m1(a)"

	// method expressions with literal receiver types
	f := interface{ m1(string) }.m1
	f(S{}, "b")
	want += " m1(b)"

	interface{ m1(string) }.m1(S{}, "c")
	want += " m1(c)"

	x := S{}
	interface{ m1(string) }.m1(x, "d")
	want += " m1(d)"

	g := struct{ T }.m2
	_ = g
	// cannot link the call below - see #22444
	// g(struct{T}{})
	// want += " m2()"

	if got != want {
		panic("got" + got + ", want" + want)
	}
}
<commit_msg>test: disable broken test for 1.10<commit_after>// run

// Copyright 2017 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.

// Test forms of method expressions T.m where T is
// a literal type.

package main

var got, want string

type I interface {
	m()
}

type S struct {
}

func (S) m()          { got += " m()" }
func (S) m1(s string) { got += " m1(" + s + ")" }

type T int

func (T) m2() { got += " m2()" }

func main() {
	// method expressions with named receiver types
	I.m(S{})
	want += " m()"

	S.m1(S{}, "a")
	want += " m1(a)"

	// method expressions with literal receiver types
	f := interface{ m1(string) }.m1
	f(S{}, "b")
	want += " m1(b)"

	interface{ m1(string) }.m1(S{}, "c")
	want += " m1(c)"

	x := S{}
	interface{ m1(string) }.m1(x, "d")
	want += " m1(d)"

	// cannot link the call below - see #22444
	// g := struct{ T }.m2
	// g(struct{T}{})
	// want += " m2()"

	if got != want {
		panic("got" + got + ", want" + want)
	}
}
<|endoftext|>


<commit_before>package convolution

import (
	"errors"
	"fmt"
	"image"
	"math"

	"github.com/urandom/drawgl"
	"github.com/urandom/graph"
	"github.com/urandom/graph/base"
)

type Convolution struct {
	base.Node
	opts ConvolutionOptions
}

type ConvolutionOptions struct {
	Kernel    Kernel
	Channel   drawgl.Channel
	Normalize bool
	Region    image.Rectangle
}

func NewConvolutionLinker(opts ConvolutionOptions) (graph.Linker, error) {
	if len(opts.Kernel.Weights()) == 0 {
		return nil, errors.New("Empty kernel")
	}

	if opts.Channel == drawgl.All {
		opts.Channel = drawgl.Red | drawgl.Green | drawgl.Blue | drawgl.Alpha
	}

	return base.NewLinkerNode(Convolution{Node: base.NewNode(), opts: opts}), nil
}

func (n Convolution) Process(wd graph.WalkData, buffers map[graph.ConnectorName]drawgl.Result, output chan<- drawgl.Result) {
	var err error
	res := drawgl.Result{Id: n.Id()}

	defer func() {
		if err != nil {
			res.Error = fmt.Errorf("Error applying convolution using %v: %v", n.opts, err)
		}
		output <- res

		wd.Close()
	}()

	r := buffers[graph.InputName]
	buf := r.Buffer
	res.Meta = r.Meta
	if buf == nil {
		err = fmt.Errorf("no input buffer")
		return
	}

	hasRegion := false
	if !n.opts.Region.Empty() {
		hasRegion = true
	}

	var weights []float64
	var offset float64
	if n.opts.Normalize {
		weights, offset = n.opts.Kernel.Normalized()
	} else {
		weights = n.opts.Kernel.Weights()
	}

	src := drawgl.CopyImage(buf)
	b := buf.Bounds()
	l := len(weights)
	size := int(math.Sqrt(float64(l)))
	half := int(size / 2)

	opaque := buf.Opaque()
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			if hasRegion && !image.Pt(x, y).In(n.opts.Region) {
				continue
			}

			var rsum, gsum, bsum, asum float64
			for cy := y - half; cy <= y+half; cy++ {
				for cx := x - half; cx <= x+half; cx++ {
					coeff := weights[l-((cy-y+half)*size+cx-x+half)-1]

					mx := cx
					my := cy
					if mx < b.Min.X {
						mx = 2*b.Min.X - mx
					} else if mx >= b.Max.X {
						mx = (b.Max.X-1)*2 - mx
					}

					if my < b.Min.Y {
						my = 2*b.Min.Y - my
					} else if my >= b.Max.Y {
						my = (b.Max.Y-1)*2 - my
					}

					c := src.NRGBA64At(mx, my)

					if n.opts.Channel&drawgl.Red > 0 {
						rsum += coeff * float64(c.R)
					}
					if n.opts.Channel&drawgl.Green > 0 {
						gsum += coeff * float64(c.G)
					}
					if n.opts.Channel&drawgl.Blue > 0 {
						bsum += coeff * float64(c.B)
					}
					if !opaque && n.opts.Channel&drawgl.Alpha > 0 {
						asum += coeff * float64(c.A)
					}
				}
			}

			c := src.NRGBA64At(x, y)

			if n.opts.Channel&drawgl.Red > 0 {
				c.R = drawgl.ClampUint16(rsum + offset)
			}
			if n.opts.Channel&drawgl.Green > 0 {
				c.G = drawgl.ClampUint16(gsum + offset)
			}
			if n.opts.Channel&drawgl.Blue > 0 {
				c.B = drawgl.ClampUint16(bsum + offset)
			}
			if !opaque && n.opts.Channel&drawgl.Alpha > 0 {
				c.A = drawgl.ClampUint16(asum + offset)
			}

			buf.SetNRGBA64(x, y, c)
		}
	}

	res.Buffer = buf
}
<commit_msg>parallelize the work<commit_after>package convolution

import (
	"errors"
	"fmt"
	"image"
	"math"
	"runtime"
	"sync"

	"github.com/urandom/drawgl"
	"github.com/urandom/graph"
	"github.com/urandom/graph/base"
)

type Convolution struct {
	base.Node
	opts ConvolutionOptions
}

type ConvolutionOptions struct {
	Kernel    Kernel
	Channel   drawgl.Channel
	Normalize bool
	Region    image.Rectangle
}

func NewConvolutionLinker(opts ConvolutionOptions) (graph.Linker, error) {
	if len(opts.Kernel.Weights()) == 0 {
		return nil, errors.New("Empty kernel")
	}

	if opts.Channel == drawgl.All {
		opts.Channel = drawgl.Red | drawgl.Green | drawgl.Blue | drawgl.Alpha
	}

	return base.NewLinkerNode(Convolution{Node: base.NewNode(), opts: opts}), nil
}

func (n Convolution) Process(wd graph.WalkData, buffers map[graph.ConnectorName]drawgl.Result, output chan<- drawgl.Result) {
	var err error
	res := drawgl.Result{Id: n.Id()}

	defer func() {
		if err != nil {
			res.Error = fmt.Errorf("Error applying convolution using %v: %v", n.opts, err)
		}
		output <- res

		wd.Close()
	}()

	r := buffers[graph.InputName]
	buf := r.Buffer
	res.Meta = r.Meta
	if buf == nil {
		err = fmt.Errorf("no input buffer")
		return
	}

	hasRegion := false
	if !n.opts.Region.Empty() {
		hasRegion = true
	}

	var weights []float64
	var offset float64
	if n.opts.Normalize {
		weights, offset = n.opts.Kernel.Normalized()
	} else {
		weights = n.opts.Kernel.Weights()
	}

	src := drawgl.CopyImage(buf)
	b := buf.Bounds()
	l := len(weights)
	size := int(math.Sqrt(float64(l)))
	half := int(size / 2)

	opaque := buf.Opaque()
	parallelRowCycler(b, func(pt image.Point) {
		if hasRegion && !pt.In(n.opts.Region) {
			return
		}

		var rsum, gsum, bsum, asum float64
		for cy := pt.Y - half; cy <= pt.Y+half; cy++ {
			for cx := pt.X - half; cx <= pt.X+half; cx++ {
				coeff := weights[l-((cy-pt.Y+half)*size+cx-pt.X+half)-1]

				mx := cx
				my := cy
				if mx < b.Min.X {
					mx = 2*b.Min.X - mx
				} else if mx >= b.Max.X {
					mx = (b.Max.X-1)*2 - mx
				}

				if my < b.Min.Y {
					my = 2*b.Min.Y - my
				} else if my >= b.Max.Y {
					my = (b.Max.Y-1)*2 - my
				}

				c := src.NRGBA64At(mx, my)

				if n.opts.Channel&drawgl.Red > 0 {
					rsum += coeff * float64(c.R)
				}
				if n.opts.Channel&drawgl.Green > 0 {
					gsum += coeff * float64(c.G)
				}
				if n.opts.Channel&drawgl.Blue > 0 {
					bsum += coeff * float64(c.B)
				}
				if !opaque && n.opts.Channel&drawgl.Alpha > 0 {
					asum += coeff * float64(c.A)
				}
			}
		}

		c := src.NRGBA64At(pt.X, pt.Y)

		if n.opts.Channel&drawgl.Red > 0 {
			c.R = drawgl.ClampUint16(rsum + offset)
		}
		if n.opts.Channel&drawgl.Green > 0 {
			c.G = drawgl.ClampUint16(gsum + offset)
		}
		if n.opts.Channel&drawgl.Blue > 0 {
			c.B = drawgl.ClampUint16(bsum + offset)
		}
		if !opaque && n.opts.Channel&drawgl.Alpha > 0 {
			c.A = drawgl.ClampUint16(asum + offset)
		}

		buf.SetNRGBA64(pt.X, pt.Y, c)
	})

	res.Buffer = buf
}

func parallelRowCycler(b image.Rectangle, fn func(pt image.Point)) {
	var wg sync.WaitGroup

	rowchan := make(chan []int)

	go func() {
		defer close(rowchan)

		capacity := 100
		i := 0
		chunk := make([]int, i, capacity)
		for y := b.Min.Y; y < b.Max.Y; y++ {
			chunk = append(chunk, y)

			if i == cap(chunk) || y == b.Max.Y-1 {
				rowchan <- chunk

				if y != b.Max.Y-1 {
					i = 0
					chunk = make([]int, 0, capacity)
				}
			} else {
				i++
			}
		}
	}()

	count := runtime.GOMAXPROCS(0)
	wg.Add(count)

	for i := 0; i < count; i++ {
		go func() {
			defer wg.Done()
			for chunk := range rowchan {
				for _, y := range chunk {
					for x := b.Min.X; x < b.Max.X; x++ {
						fn(image.Pt(x, y))
					}
				}
			}
		}()
	}

	wg.Wait()
}
<|endoftext|>