<commit_before>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package e2e

import (
	"bytes"
	"fmt"
	"os/exec"
	"path"
	"strconv"
	"strings"
	"time"

	. "github.com/onsi/ginkgo"
	clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
	"k8s.io/kubernetes/test/e2e/framework"
)

func addMasterReplica(zone string) error {
	framework.Logf(fmt.Sprintf("Adding a new master replica, zone: %s", zone))
	v, _, err := framework.RunCmd(path.Join(framework.TestContext.RepoRoot, "hack/e2e-internal/e2e-add-master.sh"), zone)
	framework.Logf("%s", v)
	if err != nil {
		return err
	}
	return nil
}

func removeMasterReplica(zone string) error {
	framework.Logf(fmt.Sprintf("Removing an existing master replica, zone: %s", zone))
	v, _, err := framework.RunCmd(path.Join(framework.TestContext.RepoRoot, "hack/e2e-internal/e2e-remove-master.sh"), zone)
	framework.Logf("%s", v)
	if err != nil {
		return err
	}
	return nil
}

func verifyRCs(c clientset.Interface, ns string, names []string) {
	for _, name := range names {
		framework.ExpectNoError(framework.VerifyPods(c, ns, name, true, 1))
	}
}

func createNewRC(c clientset.Interface, ns string, name string) {
	_, err := newRCByName(c, ns, name, 1, nil)
	framework.ExpectNoError(err)
}

func verifyNumberOfMasterReplicas(expected int) {
	output, err := exec.Command("gcloud", "compute", "instances", "list",
		"--project="+framework.TestContext.CloudConfig.ProjectID,
		"--regexp="+framework.GenerateMasterRegexp(framework.TestContext.CloudConfig.MasterName),
		"--filter=status=RUNNING",
		"--format=[no-heading]").CombinedOutput()
	framework.Logf("%s", output)
	framework.ExpectNoError(err)
	newline := []byte("\n")
	replicas := bytes.Count(output, newline)
	framework.Logf("Num master replicas/expected: %d/%d", replicas, expected)
	if replicas != expected {
		framework.Failf("Wrong number of master replicas %d expected %d", replicas, expected)
	}
}

func findRegionForZone(zone string) string {
	region, err := exec.Command("gcloud", "compute", "zones", "list", zone, "--quiet", "--format=[no-heading](region)").CombinedOutput()
	framework.ExpectNoError(err)
	if string(region) == "" {
		framework.Failf("Region not found; zone: %s", zone)
	}
	return string(region)
}

func findZonesForRegion(region string) []string {
	output, err := exec.Command("gcloud", "compute", "zones", "list", "--filter=region="+region,
		"--quiet", "--format=[no-heading](name)").CombinedOutput()
	framework.ExpectNoError(err)
	zones := strings.Split(string(output), "\n")
	return zones
}

// removeZoneFromZones removes zone from zones slide.
// Please note that entries in zones can be repeated. In such situation only one replica is removed.
func removeZoneFromZones(zones []string, zone string) []string {
	idx := -1
	for j, z := range zones {
		if z == zone {
			idx = j
			break
		}
	}
	if idx >= 0 {
		return zones[:idx+copy(zones[idx:], zones[idx+1:])]
	}
	return zones
}

var _ = framework.KubeDescribe("HA-master", func() {
	f := framework.NewDefaultFramework("ha-master")
	var c clientset.Interface
	var ns string
	var additionalReplicaZones []string
	var existingRCs []string

	BeforeEach(func() {
		framework.SkipUnlessProviderIs("gce")
		c = f.ClientSet
		ns = f.Namespace.Name
		verifyNumberOfMasterReplicas(1)
		additionalReplicaZones = make([]string, 0)
		existingRCs = make([]string, 0)
	})

	AfterEach(func() {
		// Clean-up additional master replicas if the test execution was broken.
		for _, zone := range additionalReplicaZones {
			removeMasterReplica(zone)
		}
		framework.WaitForMasters(framework.TestContext.CloudConfig.MasterName, c, 1, 10*time.Minute)
		verifyNumberOfMasterReplicas(1)
	})

	type Action int
	const (
		None Action = iota
		AddReplica
		RemoveReplica
	)

	step := func(action Action, zone string) {
		switch action {
		case None:
		case AddReplica:
			framework.ExpectNoError(addMasterReplica(zone))
			additionalReplicaZones = append(additionalReplicaZones, zone)
		case RemoveReplica:
			framework.ExpectNoError(removeMasterReplica(zone))
			additionalReplicaZones = removeZoneFromZones(additionalReplicaZones, zone)
		}
		verifyNumberOfMasterReplicas(len(additionalReplicaZones) + 1)
		framework.WaitForMasters(framework.TestContext.CloudConfig.MasterName, c, len(additionalReplicaZones)+1, 10*time.Minute)

		// Verify that API server works correctly with HA master.
		rcName := "ha-master-" + strconv.Itoa(len(existingRCs))
		createNewRC(c, ns, rcName)
		existingRCs = append(existingRCs, rcName)
		verifyRCs(c, ns, existingRCs)
	}

	It("survive addition/removal replicas same zone [Serial][Disruptive]", func() {
		zone := framework.TestContext.CloudConfig.Zone
		step(None, "")
		numAdditionalReplicas := 2
		for i := 0; i < numAdditionalReplicas; i++ {
			step(AddReplica, zone)
		}
		for i := 0; i < numAdditionalReplicas; i++ {
			step(RemoveReplica, zone)
		}
	})

	It("survive addition/removal replicas different zones [Serial][Disruptive]", func() {
		zone := framework.TestContext.CloudConfig.Zone
		region := findRegionForZone(zone)
		zones := findZonesForRegion(region)
		zones = removeZoneFromZones(zones, zone)

		step(None, "")
		// If numAdditionalReplicas is larger then the number of remaining zones in the region,
		// we create a few masters in the same zone and zone entry is repeated in additionalReplicaZones.
		numAdditionalReplicas := 2
		for i := 0; i < numAdditionalReplicas; i++ {
			step(AddReplica, zones[i%len(zones)])
		}
		for i := 0; i < numAdditionalReplicas; i++ {
			step(RemoveReplica, zones[i%len(zones)])
		}
	})
})
<commit_msg>Revert "Removed "feature" tag"<commit_after>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package e2e

import (
	"bytes"
	"fmt"
	"os/exec"
	"path"
	"strconv"
	"strings"
	"time"

	. "github.com/onsi/ginkgo"
	clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
	"k8s.io/kubernetes/test/e2e/framework"
)

func addMasterReplica(zone string) error {
	framework.Logf(fmt.Sprintf("Adding a new master replica, zone: %s", zone))
	v, _, err := framework.RunCmd(path.Join(framework.TestContext.RepoRoot, "hack/e2e-internal/e2e-add-master.sh"), zone)
	framework.Logf("%s", v)
	if err != nil {
		return err
	}
	return nil
}

func removeMasterReplica(zone string) error {
	framework.Logf(fmt.Sprintf("Removing an existing master replica, zone: %s", zone))
	v, _, err := framework.RunCmd(path.Join(framework.TestContext.RepoRoot, "hack/e2e-internal/e2e-remove-master.sh"), zone)
	framework.Logf("%s", v)
	if err != nil {
		return err
	}
	return nil
}

func verifyRCs(c clientset.Interface, ns string, names []string) {
	for _, name := range names {
		framework.ExpectNoError(framework.VerifyPods(c, ns, name, true, 1))
	}
}

func createNewRC(c clientset.Interface, ns string, name string) {
	_, err := newRCByName(c, ns, name, 1, nil)
	framework.ExpectNoError(err)
}

func verifyNumberOfMasterReplicas(expected int) {
	output, err := exec.Command("gcloud", "compute", "instances", "list",
		"--project="+framework.TestContext.CloudConfig.ProjectID,
		"--regexp="+framework.GenerateMasterRegexp(framework.TestContext.CloudConfig.MasterName),
		"--filter=status=RUNNING",
		"--format=[no-heading]").CombinedOutput()
	framework.Logf("%s", output)
	framework.ExpectNoError(err)
	newline := []byte("\n")
	replicas := bytes.Count(output, newline)
	framework.Logf("Num master replicas/expected: %d/%d", replicas, expected)
	if replicas != expected {
		framework.Failf("Wrong number of master replicas %d expected %d", replicas, expected)
	}
}

func findRegionForZone(zone string) string {
	region, err := exec.Command("gcloud", "compute", "zones", "list", zone, "--quiet", "--format=[no-heading](region)").CombinedOutput()
	framework.ExpectNoError(err)
	if string(region) == "" {
		framework.Failf("Region not found; zone: %s", zone)
	}
	return string(region)
}

func findZonesForRegion(region string) []string {
	output, err := exec.Command("gcloud", "compute", "zones", "list", "--filter=region="+region,
		"--quiet", "--format=[no-heading](name)").CombinedOutput()
	framework.ExpectNoError(err)
	zones := strings.Split(string(output), "\n")
	return zones
}

// removeZoneFromZones removes zone from zones slide.
// Please note that entries in zones can be repeated. In such situation only one replica is removed.
func removeZoneFromZones(zones []string, zone string) []string {
	idx := -1
	for j, z := range zones {
		if z == zone {
			idx = j
			break
		}
	}
	if idx >= 0 {
		return zones[:idx+copy(zones[idx:], zones[idx+1:])]
	}
	return zones
}

var _ = framework.KubeDescribe("HA-master [Feature:HAMaster]", func() {
	f := framework.NewDefaultFramework("ha-master")
	var c clientset.Interface
	var ns string
	var additionalReplicaZones []string
	var existingRCs []string

	BeforeEach(func() {
		framework.SkipUnlessProviderIs("gce")
		c = f.ClientSet
		ns = f.Namespace.Name
		verifyNumberOfMasterReplicas(1)
		additionalReplicaZones = make([]string, 0)
		existingRCs = make([]string, 0)
	})

	AfterEach(func() {
		// Clean-up additional master replicas if the test execution was broken.
		for _, zone := range additionalReplicaZones {
			removeMasterReplica(zone)
		}
		framework.WaitForMasters(framework.TestContext.CloudConfig.MasterName, c, 1, 10*time.Minute)
		verifyNumberOfMasterReplicas(1)
	})

	type Action int
	const (
		None Action = iota
		AddReplica
		RemoveReplica
	)

	step := func(action Action, zone string) {
		switch action {
		case None:
		case AddReplica:
			framework.ExpectNoError(addMasterReplica(zone))
			additionalReplicaZones = append(additionalReplicaZones, zone)
		case RemoveReplica:
			framework.ExpectNoError(removeMasterReplica(zone))
			additionalReplicaZones = removeZoneFromZones(additionalReplicaZones, zone)
		}
		verifyNumberOfMasterReplicas(len(additionalReplicaZones) + 1)
		framework.WaitForMasters(framework.TestContext.CloudConfig.MasterName, c, len(additionalReplicaZones)+1, 10*time.Minute)

		// Verify that API server works correctly with HA master.
		rcName := "ha-master-" + strconv.Itoa(len(existingRCs))
		createNewRC(c, ns, rcName)
		existingRCs = append(existingRCs, rcName)
		verifyRCs(c, ns, existingRCs)
	}

	It("survive addition/removal replicas same zone [Serial][Disruptive]", func() {
		zone := framework.TestContext.CloudConfig.Zone
		step(None, "")
		numAdditionalReplicas := 2
		for i := 0; i < numAdditionalReplicas; i++ {
			step(AddReplica, zone)
		}
		for i := 0; i < numAdditionalReplicas; i++ {
			step(RemoveReplica, zone)
		}
	})

	It("survive addition/removal replicas different zones [Serial][Disruptive]", func() {
		zone := framework.TestContext.CloudConfig.Zone
		region := findRegionForZone(zone)
		zones := findZonesForRegion(region)
		zones = removeZoneFromZones(zones, zone)

		step(None, "")
		// If numAdditionalReplicas is larger then the number of remaining zones in the region,
		// we create a few masters in the same zone and zone entry is repeated in additionalReplicaZones.
		numAdditionalReplicas := 2
		for i := 0; i < numAdditionalReplicas; i++ {
			step(AddReplica, zones[i%len(zones)])
		}
		for i := 0; i < numAdditionalReplicas; i++ {
			step(RemoveReplica, zones[i%len(zones)])
		}
	})
})
<|endoftext|>


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

package e2e

import (
	"flag"
	"log"
	"os"
	"os/user"
	"path/filepath"
	"testing"

	e2eframework "agones.dev/agones/test/e2e/framework"
)

const defaultNs = "default"

var framework *e2eframework.Framework

func TestMain(m *testing.M) {
	usr, _ := user.Current()
	kubeconfig := flag.String("kubeconfig", filepath.Join(usr.HomeDir, "/.kube/config"),
		"kube config path, e.g. $HOME/.kube/config")
	gsimage := flag.String("gameserver-image", "gcr.io/agones-images/udp-server:0.6",
		"gameserver image to use for those tests, gcr.io/agones-images/udp-server:0.6")
	pullSecret := flag.String("pullsecret", "",
		"optional secret to be used for pulling the gameserver and/or Agones SDK sidecar images")
	stressTestLevel := flag.Int("stress", 0, "enable stress test at given level 0-100")

	flag.Parse()

	var (
		err      error
		exitCode int
	)

	if framework, err = e2eframework.New(*kubeconfig, *gsimage, *pullSecret, *stressTestLevel); err != nil {
		log.Printf("failed to setup framework: %v\n", err)
		os.Exit(1)
	}

	// run cleanup before tests, to ensure no resources from previous runs exist.
	err = framework.CleanUp(defaultNs)
	if err != nil {
		log.Printf("failed to cleanup resources: %v\n", err)
	}

	defer func() {
		err = framework.CleanUp(defaultNs)
		if err != nil {
			log.Printf("failed to cleanup resources: %v\n", err)
		}
		os.Exit(exitCode)
	}()
	exitCode = m.Run()

}
<commit_msg>test: make e2e test logs more readable<commit_after>// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package e2e

import (
	"flag"
	"log"
	"os"
	"os/user"
	"path/filepath"
	"testing"

	e2eframework "agones.dev/agones/test/e2e/framework"
	"github.com/sirupsen/logrus"
)

const defaultNs = "default"

var framework *e2eframework.Framework

func TestMain(m *testing.M) {
	usr, _ := user.Current()
	kubeconfig := flag.String("kubeconfig", filepath.Join(usr.HomeDir, "/.kube/config"),
		"kube config path, e.g. $HOME/.kube/config")
	gsimage := flag.String("gameserver-image", "gcr.io/agones-images/udp-server:0.6",
		"gameserver image to use for those tests, gcr.io/agones-images/udp-server:0.6")
	pullSecret := flag.String("pullsecret", "",
		"optional secret to be used for pulling the gameserver and/or Agones SDK sidecar images")
	stressTestLevel := flag.Int("stress", 0, "enable stress test at given level 0-100")

	flag.Parse()

	logrus.SetFormatter(&logrus.TextFormatter{
		EnvironmentOverrideColors: true,
		FullTimestamp:             true,
		TimestampFormat:           "2006-01-02 15:04:06.000",
	})

	var (
		err      error
		exitCode int
	)

	if framework, err = e2eframework.New(*kubeconfig, *gsimage, *pullSecret, *stressTestLevel); err != nil {
		log.Printf("failed to setup framework: %v\n", err)
		os.Exit(1)
	}

	// run cleanup before tests, to ensure no resources from previous runs exist.
	err = framework.CleanUp(defaultNs)
	if err != nil {
		log.Printf("failed to cleanup resources: %v\n", err)
	}

	defer func() {
		err = framework.CleanUp(defaultNs)
		if err != nil {
			log.Printf("failed to cleanup resources: %v\n", err)
		}
		os.Exit(exitCode)
	}()
	exitCode = m.Run()

}
<|endoftext|>


<commit_before>package core

import (
	"github.com/MG-RAST/AWE/lib/core/uuid"
	"github.com/MG-RAST/AWE/lib/logger"
	//"strings"
	"sync"
	"time"
)

// This RWLock keeps track of the owener and of each reader
// Because channels are used for the locking mechanism, you can use locks with timeouts.
// Each reader gets a ReadLock object that has to be used to unlock after reading is done.

type ReadLock struct {
	id string
}

type RWMutex struct {
	//sync.RWMutex `bson:"-" json:"-"` // Locks only members that can change. Current_work has its own lock.
	writeLock chan int
	lockOwner string            `bson:"-" json:"-"`
	Name      string            `bson:"-" json:"-"`
	readers   map[string]string // map[Id]Name
	readLock  sync.Mutex
}

func (m *RWMutex) Init(name string) {
	m.Name = name
	m.writeLock = make(chan int, 1)
	m.readers = make(map[string]string)
	m.lockOwner = "nobody_init"

	if name == "" {
		panic("name not defined")
	}

	m.writeLock <- 1 // Put the initial value into the channel

	return
}

func (r *ReadLock) Get_Id() string {
	return r.id
}

func (m *RWMutex) Lock() {
	panic("Lock() was called")
	m.LockNamed("unknown")
}

func (m *RWMutex) LockNamed(name string) {
	//logger.Debug(3, "Lock")
	//reader_list := strings.Join(m.RList(), ",")
	//logger.Debug(3, "(%s) %s requests Lock. current owner:  %s (reader list :%s)", m.Name, name, m.lockOwner, reader_list)
	if m.Name == "" {
		panic("LockNamed: object has no name")
	}
	//m.RWMutex.Lock()
	<-m.writeLock // Grab the ticket
	m.lockOwner = name

	// wait for Readers to leave....

	for m.RCount() > 0 {
		time.Sleep(100)
	}

	//logger.Debug(3, "(%s) LOCKED by %s", m.Name, name)
}

func (m *RWMutex) Unlock() {
	//logger.Debug(3, "Unlock")
	old_owner := m.lockOwner
	m.lockOwner = "nobody_anymore"
	//m.RWMutex.Unlock()
	m.writeLock <- 1 // Give it back
	logger.Debug(3, "(%s) UNLOCKED by %s **********************", m.Name, old_owner)
}

func (m *RWMutex) RLockNamed(name string) ReadLock {
	logger.Debug(3, "(%s) request RLock and Lock.", m.Name)
	if m.Name == "" {
		panic("xzy name empty")
	}
	m.LockNamed("RLock")
	logger.Debug(3, "(%s) RLock got Lock.", m.Name)
	m.readLock.Lock()
	new_uuid := uuid.New()

	m.readers[new_uuid] = name

	//m.readCounter += 1
	m.readLock.Unlock()
	m.Unlock()
	logger.Debug(3, "(%s) got RLock.", m.Name)
	return ReadLock{id: new_uuid}
}

func (m *RWMutex) RLock() {
	panic("RLock() was called")
}
func (m *RWMutex) RUnlock() {
	panic("RUnlock() was called")
}

func (m *RWMutex) RUnlockNamed(rl ReadLock) {

	lock_uuid := rl.Get_Id()

	logger.Debug(3, "(%s) request RUnlock.", m.Name)
	m.readLock.Lock()
	//m.readCounter -= 1
	name, ok := m.readers[lock_uuid]
	if ok {
		delete(m.readers, lock_uuid)
		logger.Debug(3, "(%s) %s did RUnlock.", m.Name, name)
	} else {
		logger.Debug(3, "(%s) ERROR: %s did not have RLock !?!??!?!?.", m.Name, name)
	}
	m.readLock.Unlock()
	logger.Debug(3, "(%s) did RUnlock.", m.Name)
}

func (m *RWMutex) RCount() (c int) {

	m.readLock.Lock()
	c = len(m.readers)
	m.readLock.Unlock()
	return
}

func (m *RWMutex) RList() (list []string) {

	m.readLock.Lock()
	for _, v := range m.readers {
		list = append(list, v)
	}
	m.readLock.Unlock()
	return
}
<commit_msg>show LOCK debug output<commit_after>package core

import (
	"github.com/MG-RAST/AWE/lib/core/uuid"
	"github.com/MG-RAST/AWE/lib/logger"
	"strings"
	"sync"
	"time"
)

// This RWLock keeps track of the owener and of each reader
// Because channels are used for the locking mechanism, you can use locks with timeouts.
// Each reader gets a ReadLock object that has to be used to unlock after reading is done.

type ReadLock struct {
	id string
}

type RWMutex struct {
	//sync.RWMutex `bson:"-" json:"-"` // Locks only members that can change. Current_work has its own lock.
	writeLock chan int
	lockOwner string            `bson:"-" json:"-"`
	Name      string            `bson:"-" json:"-"`
	readers   map[string]string // map[Id]Name
	readLock  sync.Mutex
}

func (m *RWMutex) Init(name string) {
	m.Name = name
	m.writeLock = make(chan int, 1)
	m.readers = make(map[string]string)
	m.lockOwner = "nobody_init"

	if name == "" {
		panic("name not defined")
	}

	m.writeLock <- 1 // Put the initial value into the channel

	return
}

func (r *ReadLock) Get_Id() string {
	return r.id
}

func (m *RWMutex) Lock() {
	panic("Lock() was called")
	m.LockNamed("unknown")
}

func (m *RWMutex) LockNamed(name string) {
	//logger.Debug(3, "Lock")
	reader_list := strings.Join(m.RList(), ",")
	logger.Debug(3, "(%s) %s requests Lock. current owner:  %s (reader list :%s)", m.Name, name, m.lockOwner, reader_list)
	if m.Name == "" {
		panic("LockNamed: object has no name")
	}
	//m.RWMutex.Lock()
	<-m.writeLock // Grab the ticket
	m.lockOwner = name

	// wait for Readers to leave....

	for m.RCount() > 0 {
		time.Sleep(100)
	}

	logger.Debug(3, "(%s) LOCKED by %s", m.Name, name)
}

func (m *RWMutex) Unlock() {
	//logger.Debug(3, "Unlock")
	old_owner := m.lockOwner
	m.lockOwner = "nobody_anymore"
	//m.RWMutex.Unlock()
	m.writeLock <- 1 // Give it back
	logger.Debug(3, "(%s) UNLOCKED by %s **********************", m.Name, old_owner)
}

func (m *RWMutex) RLockNamed(name string) ReadLock {
	logger.Debug(3, "(%s) request RLock and Lock.", m.Name)
	if m.Name == "" {
		panic("xzy name empty")
	}
	m.LockNamed("RLock")
	logger.Debug(3, "(%s) RLock got Lock.", m.Name)
	m.readLock.Lock()
	new_uuid := uuid.New()

	m.readers[new_uuid] = name

	//m.readCounter += 1
	m.readLock.Unlock()
	m.Unlock()
	logger.Debug(3, "(%s) got RLock.", m.Name)
	return ReadLock{id: new_uuid}
}

func (m *RWMutex) RLock() {
	panic("RLock() was called")
}
func (m *RWMutex) RUnlock() {
	panic("RUnlock() was called")
}

func (m *RWMutex) RUnlockNamed(rl ReadLock) {

	lock_uuid := rl.Get_Id()

	logger.Debug(3, "(%s) request RUnlock.", m.Name)
	m.readLock.Lock()
	//m.readCounter -= 1
	name, ok := m.readers[lock_uuid]
	if ok {
		delete(m.readers, lock_uuid)
		logger.Debug(3, "(%s) %s did RUnlock.", m.Name, name)
	} else {
		logger.Debug(3, "(%s) ERROR: %s did not have RLock !?!??!?!?.", m.Name, name)
	}
	m.readLock.Unlock()
	logger.Debug(3, "(%s) did RUnlock.", m.Name)
}

func (m *RWMutex) RCount() (c int) {

	m.readLock.Lock()
	c = len(m.readers)
	m.readLock.Unlock()
	return
}

func (m *RWMutex) RList() (list []string) {

	m.readLock.Lock()
	for _, v := range m.readers {
		list = append(list, v)
	}
	m.readLock.Unlock()
	return
}
<|endoftext|>


<commit_before>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENE file.

package leveldb

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"
	"testing"

	"github.com/syndtr/goleveldb/leveldb/storage"
	"github.com/syndtr/goleveldb/leveldb/util"
)

const typeShift = 3

var (
	tsErrInvalidFile = errors.New("leveldb.testStorage: invalid file for argument")
	tsErrFileOpen    = errors.New("leveldb.testStorage: file still open")
)

var (
	tsKeepFS = os.Getenv("GOLEVELDB_USEFS") == "2"
	tsFS     = tsKeepFS || os.Getenv("GOLEVELDB_USEFS") == "1"
	tsMU     = &sync.Mutex{}
	tsNum    = 0
)

type tsLock struct {
	ts *testStorage
	r  util.Releaser
}

func (l tsLock) Release() {
	l.r.Release()
	l.ts.t.Log("I: storage lock released")
}

type tsReader struct {
	tf tsFile
	storage.Reader
}

func (tr tsReader) Read(b []byte) (n int, err error) {
	ts := tr.tf.ts
	ts.countRead(tr.tf.Type())
	n, err = tr.Reader.Read(b)
	if err != nil && err != io.EOF {
		ts.t.Errorf("E: read error, num=%d type=%v n=%d: %v", tr.tf.Num(), tr.tf.Type(), n, err)
	}
	return
}

func (tr tsReader) Close() (err error) {
	err = tr.Reader.Close()
	tr.tf.close("reader", err)
	return
}

type tsWriter struct {
	tf tsFile
	storage.Writer
}

func (tw tsWriter) Write(b []byte) (n int, err error) {
	ts := tw.tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	if ts.emuWriteErr&tw.tf.Type() != 0 {
		return 0, errors.New("leveldb.testStorage: emulated write error")
	}
	n, err = tw.Writer.Write(b)
	if err != nil {
		ts.t.Errorf("E: write error, num=%d type=%v n=%d: %v", tw.tf.Num(), tw.tf.Type(), n, err)
	}
	return
}

func (tw tsWriter) Sync() (err error) {
	ts := tw.tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	for ts.emuDelaySync&tw.tf.Type() != 0 {
		ts.cond.Wait()
	}
	if ts.emuSyncErr&tw.tf.Type() != 0 {
		return errors.New("leveldb.testStorage: emulated sync error")
	}
	err = tw.Writer.Sync()
	if err != nil {
		ts.t.Errorf("E: sync error, num=%d type=%v: %v", tw.tf.Num(), tw.tf.Type(), err)
	}
	return
}

func (tw tsWriter) Close() (err error) {
	err = tw.Writer.Close()
	tw.tf.close("reader", err)
	return
}

type tsFile struct {
	ts *testStorage
	storage.File
}

func (tf tsFile) x() uint64 {
	return tf.Num()<<typeShift | uint64(tf.Type())
}

func (tf tsFile) checkOpen(m string) error {
	ts := tf.ts
	if writer, ok := ts.opens[tf.x()]; ok {
		if writer {
			ts.t.Errorf("E: cannot %s file, num=%d type=%v: a writer still open", m, tf.Num(), tf.Type())
		} else {
			ts.t.Errorf("E: cannot %s file, num=%d type=%v: a reader still open", m, tf.Num(), tf.Type())
		}
		return tsErrFileOpen
	}
	return nil
}

func (tf tsFile) close(m string, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	if _, ok := ts.opens[tf.x()]; !ok {
		ts.t.Errorf("E: %s: redudant file closing, num=%d type=%v", m, tf.Num(), tf.Type())
	} else if err == nil {
		ts.t.Logf("I: %s: file closed, num=%d type=%v", m, tf.Num(), tf.Type())
	}
	delete(ts.opens, tf.x())
	if err != nil {
		ts.t.Errorf("E: %s: cannot close file, num=%d type=%v: %v", m, tf.Num(), tf.Type(), err)
	}
}

func (tf tsFile) Open() (r storage.Reader, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("open")
	if err != nil {
		return
	}
	r, err = tf.File.Open()
	if err != nil {
		ts.t.Errorf("E: cannot open file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file opened, num=%d type=%v", tf.Num(), tf.Type())
		ts.opens[tf.x()] = false
		r = tsReader{tf, r}
	}
	return
}

func (tf tsFile) Create() (w storage.Writer, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("create")
	if err != nil {
		return
	}
	w, err = tf.File.Create()
	if err != nil {
		ts.t.Errorf("E: cannot create file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file created, num=%d type=%v", tf.Num(), tf.Type())
		ts.opens[tf.x()] = true
		w = tsWriter{tf, w}
	}
	return
}

func (tf tsFile) Remove() (err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("remove")
	if err != nil {
		return
	}
	err = tf.File.Remove()
	if err != nil {
		ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file removed, num=%d type=%v", tf.Num(), tf.Type())
	}
	return
}

type testStorage struct {
	t *testing.T
	storage.Storage
	closeFn func() error

	mu   sync.Mutex
	cond sync.Cond
	// Open files, true=writer, false=reader
	opens        map[uint64]bool
	emuDelaySync storage.FileType
	emuWriteErr  storage.FileType
	emuSyncErr   storage.FileType
	readCnt      uint64
	readCntEn    storage.FileType
}

func (ts *testStorage) DelaySync(t storage.FileType) {
	ts.mu.Lock()
	ts.emuDelaySync |= t
	ts.cond.Broadcast()
	ts.mu.Unlock()
}

func (ts *testStorage) ReleaseSync(t storage.FileType) {
	ts.mu.Lock()
	ts.emuDelaySync &= ^t
	ts.cond.Broadcast()
	ts.mu.Unlock()
}

func (ts *testStorage) SetWriteErr(t storage.FileType) {
	ts.mu.Lock()
	ts.emuWriteErr = t
	ts.mu.Unlock()
}

func (ts *testStorage) SetSyncErr(t storage.FileType) {
	ts.mu.Lock()
	ts.emuSyncErr = t
	ts.mu.Unlock()
}

func (ts *testStorage) ReadCounter() uint64 {
	ts.mu.Lock()
	defer ts.mu.Unlock()
	return ts.readCnt
}

func (ts *testStorage) ResetReadCounter() {
	ts.mu.Lock()
	ts.readCnt = 0
	ts.mu.Unlock()
}

func (ts *testStorage) SetReadCounter(t storage.FileType) {
	ts.mu.Lock()
	ts.readCntEn = t
	ts.mu.Unlock()
}

func (ts *testStorage) countRead(t storage.FileType) {
	ts.mu.Lock()
	if ts.readCntEn&t != 0 {
		ts.readCnt++
	}
	ts.mu.Unlock()
}

func (ts *testStorage) Lock() (r util.Releaser, err error) {
	r, err = ts.Storage.Lock()
	if err != nil {
		ts.t.Logf("W: storage locking failed: %v", err)
	} else {
		ts.t.Log("I: storage locked")
		r = tsLock{ts, r}
	}
	return
}

func (ts *testStorage) Log(str string) {
	ts.t.Log("L: " + str)
	ts.Storage.Log(str)
}

func (ts *testStorage) GetFile(num uint64, t storage.FileType) storage.File {
	return tsFile{ts, ts.Storage.GetFile(num, t)}
}

func (ts *testStorage) GetFiles(t storage.FileType) (ff []storage.File, err error) {
	ff0, err := ts.Storage.GetFiles(t)
	if err != nil {
		ts.t.Errorf("E: get files failed: %v", err)
		return
	}
	ff = make([]storage.File, len(ff0))
	for i, f := range ff0 {
		ff[i] = tsFile{ts, f}
	}
	ts.t.Logf("I: get files, type=0x%x count=%d", int(t), len(ff))
	return
}

func (ts *testStorage) GetManifest() (f storage.File, err error) {
	f0, err := ts.Storage.GetManifest()
	if err != nil {
		if !os.IsNotExist(err) {
			ts.t.Errorf("E: get manifest failed: %v", err)
		}
		return
	}
	f = tsFile{ts, f0}
	ts.t.Logf("I: get manifest, num=%d", f.Num())
	return
}

func (ts *testStorage) SetManifest(f storage.File) error {
	tf, ok := f.(tsFile)
	if !ok {
		ts.t.Error("E: set manifest failed: type assertion failed")
		return tsErrInvalidFile
	} else if tf.Type() != storage.TypeManifest {
		ts.t.Errorf("E: set manifest failed: invalid file type: %s", tf.Type())
		return tsErrInvalidFile
	}
	err := ts.Storage.SetManifest(tf.File)
	if err != nil {
		ts.t.Errorf("E: set manifest failed: %v", err)
	} else {
		ts.t.Logf("I: set manifest, num=%d", tf.Num())
	}
	return err
}

func (ts *testStorage) Close() error {
	ts.CloseCheck()
	err := ts.Storage.Close()
	if err != nil {
		ts.t.Errorf("E: closing storage failed: %v", err)
	} else {
		ts.t.Log("I: storage closed")
	}
	if ts.closeFn != nil {
		if err := ts.closeFn(); err != nil {
			ts.t.Errorf("E: close function: %v", err)
		}
	}
	return err
}

func (ts *testStorage) CloseCheck() {
	ts.mu.Lock()
	if len(ts.opens) == 0 {
		ts.t.Log("I: all files are closed")
	} else {
		ts.t.Errorf("E: %d files still open", len(ts.opens))
		for x, writer := range ts.opens {
			num, tt := x>>typeShift, storage.FileType(x)&storage.TypeAll
			ts.t.Errorf("E: * num=%d type=%v writer=%v", num, tt, writer)
		}
	}
	ts.mu.Unlock()
}

func newTestStorage(t *testing.T) *testStorage {
	var stor storage.Storage
	var closeFn func() error
	if tsFS {
		for {
			tsMU.Lock()
			num := tsNum
			tsNum++
			tsMU.Unlock()
			path := filepath.Join(os.TempDir(), fmt.Sprintf("goleveldb-test%d0%d0%d", os.Getuid(), os.Getpid(), num))
			if _, err := os.Stat(path); err != nil {
				stor, err = storage.OpenFile(path)
				if err != nil {
					t.Fatalf("F: cannot create storage: %v", err)
				}
				t.Logf("I: storage created: %s", path)
				closeFn = func() error {
					for _, name := range []string{"LOG.old", "LOG"} {
						f, err := os.Open(filepath.Join(path, name))
						if err != nil {
							continue
						}
						if log, err := ioutil.ReadAll(f); err != nil {
							t.Logf("---------------------- %s ----------------------", name)
							t.Logf("cannot read log: %v", err)
						} else {
							t.Logf("---------------------- %s ----------------------\n%s", name, string(log))
						}
						f.Close()
						t.Logf("---------------------- %s ----------------------", name)
					}
					if tsKeepFS {
						return nil
					}
					return os.RemoveAll(path)
				}

				break
			}
		}
	} else {
		stor = storage.NewMemStorage()
	}
	ts := &testStorage{
		t:       t,
		Storage: stor,
		closeFn: closeFn,
		opens:   make(map[uint64]bool),
	}
	ts.cond.L = &ts.mu
	return ts
}
<commit_msg>leveldb: testStorage: Don't print the LOG header and footer if the file is empty<commit_after>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENE file.

package leveldb

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sync"
	"testing"

	"github.com/syndtr/goleveldb/leveldb/storage"
	"github.com/syndtr/goleveldb/leveldb/util"
)

const typeShift = 3

var (
	tsErrInvalidFile = errors.New("leveldb.testStorage: invalid file for argument")
	tsErrFileOpen    = errors.New("leveldb.testStorage: file still open")
)

var (
	tsKeepFS = os.Getenv("GOLEVELDB_USEFS") == "2"
	tsFS     = tsKeepFS || os.Getenv("GOLEVELDB_USEFS") == "1"
	tsMU     = &sync.Mutex{}
	tsNum    = 0
)

type tsLock struct {
	ts *testStorage
	r  util.Releaser
}

func (l tsLock) Release() {
	l.r.Release()
	l.ts.t.Log("I: storage lock released")
}

type tsReader struct {
	tf tsFile
	storage.Reader
}

func (tr tsReader) Read(b []byte) (n int, err error) {
	ts := tr.tf.ts
	ts.countRead(tr.tf.Type())
	n, err = tr.Reader.Read(b)
	if err != nil && err != io.EOF {
		ts.t.Errorf("E: read error, num=%d type=%v n=%d: %v", tr.tf.Num(), tr.tf.Type(), n, err)
	}
	return
}

func (tr tsReader) Close() (err error) {
	err = tr.Reader.Close()
	tr.tf.close("reader", err)
	return
}

type tsWriter struct {
	tf tsFile
	storage.Writer
}

func (tw tsWriter) Write(b []byte) (n int, err error) {
	ts := tw.tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	if ts.emuWriteErr&tw.tf.Type() != 0 {
		return 0, errors.New("leveldb.testStorage: emulated write error")
	}
	n, err = tw.Writer.Write(b)
	if err != nil {
		ts.t.Errorf("E: write error, num=%d type=%v n=%d: %v", tw.tf.Num(), tw.tf.Type(), n, err)
	}
	return
}

func (tw tsWriter) Sync() (err error) {
	ts := tw.tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	for ts.emuDelaySync&tw.tf.Type() != 0 {
		ts.cond.Wait()
	}
	if ts.emuSyncErr&tw.tf.Type() != 0 {
		return errors.New("leveldb.testStorage: emulated sync error")
	}
	err = tw.Writer.Sync()
	if err != nil {
		ts.t.Errorf("E: sync error, num=%d type=%v: %v", tw.tf.Num(), tw.tf.Type(), err)
	}
	return
}

func (tw tsWriter) Close() (err error) {
	err = tw.Writer.Close()
	tw.tf.close("reader", err)
	return
}

type tsFile struct {
	ts *testStorage
	storage.File
}

func (tf tsFile) x() uint64 {
	return tf.Num()<<typeShift | uint64(tf.Type())
}

func (tf tsFile) checkOpen(m string) error {
	ts := tf.ts
	if writer, ok := ts.opens[tf.x()]; ok {
		if writer {
			ts.t.Errorf("E: cannot %s file, num=%d type=%v: a writer still open", m, tf.Num(), tf.Type())
		} else {
			ts.t.Errorf("E: cannot %s file, num=%d type=%v: a reader still open", m, tf.Num(), tf.Type())
		}
		return tsErrFileOpen
	}
	return nil
}

func (tf tsFile) close(m string, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	if _, ok := ts.opens[tf.x()]; !ok {
		ts.t.Errorf("E: %s: redudant file closing, num=%d type=%v", m, tf.Num(), tf.Type())
	} else if err == nil {
		ts.t.Logf("I: %s: file closed, num=%d type=%v", m, tf.Num(), tf.Type())
	}
	delete(ts.opens, tf.x())
	if err != nil {
		ts.t.Errorf("E: %s: cannot close file, num=%d type=%v: %v", m, tf.Num(), tf.Type(), err)
	}
}

func (tf tsFile) Open() (r storage.Reader, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("open")
	if err != nil {
		return
	}
	r, err = tf.File.Open()
	if err != nil {
		ts.t.Errorf("E: cannot open file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file opened, num=%d type=%v", tf.Num(), tf.Type())
		ts.opens[tf.x()] = false
		r = tsReader{tf, r}
	}
	return
}

func (tf tsFile) Create() (w storage.Writer, err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("create")
	if err != nil {
		return
	}
	w, err = tf.File.Create()
	if err != nil {
		ts.t.Errorf("E: cannot create file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file created, num=%d type=%v", tf.Num(), tf.Type())
		ts.opens[tf.x()] = true
		w = tsWriter{tf, w}
	}
	return
}

func (tf tsFile) Remove() (err error) {
	ts := tf.ts
	ts.mu.Lock()
	defer ts.mu.Unlock()
	err = tf.checkOpen("remove")
	if err != nil {
		return
	}
	err = tf.File.Remove()
	if err != nil {
		ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
	} else {
		ts.t.Logf("I: file removed, num=%d type=%v", tf.Num(), tf.Type())
	}
	return
}

type testStorage struct {
	t *testing.T
	storage.Storage
	closeFn func() error

	mu   sync.Mutex
	cond sync.Cond
	// Open files, true=writer, false=reader
	opens        map[uint64]bool
	emuDelaySync storage.FileType
	emuWriteErr  storage.FileType
	emuSyncErr   storage.FileType
	readCnt      uint64
	readCntEn    storage.FileType
}

func (ts *testStorage) DelaySync(t storage.FileType) {
	ts.mu.Lock()
	ts.emuDelaySync |= t
	ts.cond.Broadcast()
	ts.mu.Unlock()
}

func (ts *testStorage) ReleaseSync(t storage.FileType) {
	ts.mu.Lock()
	ts.emuDelaySync &= ^t
	ts.cond.Broadcast()
	ts.mu.Unlock()
}

func (ts *testStorage) SetWriteErr(t storage.FileType) {
	ts.mu.Lock()
	ts.emuWriteErr = t
	ts.mu.Unlock()
}

func (ts *testStorage) SetSyncErr(t storage.FileType) {
	ts.mu.Lock()
	ts.emuSyncErr = t
	ts.mu.Unlock()
}

func (ts *testStorage) ReadCounter() uint64 {
	ts.mu.Lock()
	defer ts.mu.Unlock()
	return ts.readCnt
}

func (ts *testStorage) ResetReadCounter() {
	ts.mu.Lock()
	ts.readCnt = 0
	ts.mu.Unlock()
}

func (ts *testStorage) SetReadCounter(t storage.FileType) {
	ts.mu.Lock()
	ts.readCntEn = t
	ts.mu.Unlock()
}

func (ts *testStorage) countRead(t storage.FileType) {
	ts.mu.Lock()
	if ts.readCntEn&t != 0 {
		ts.readCnt++
	}
	ts.mu.Unlock()
}

func (ts *testStorage) Lock() (r util.Releaser, err error) {
	r, err = ts.Storage.Lock()
	if err != nil {
		ts.t.Logf("W: storage locking failed: %v", err)
	} else {
		ts.t.Log("I: storage locked")
		r = tsLock{ts, r}
	}
	return
}

func (ts *testStorage) Log(str string) {
	ts.t.Log("L: " + str)
	ts.Storage.Log(str)
}

func (ts *testStorage) GetFile(num uint64, t storage.FileType) storage.File {
	return tsFile{ts, ts.Storage.GetFile(num, t)}
}

func (ts *testStorage) GetFiles(t storage.FileType) (ff []storage.File, err error) {
	ff0, err := ts.Storage.GetFiles(t)
	if err != nil {
		ts.t.Errorf("E: get files failed: %v", err)
		return
	}
	ff = make([]storage.File, len(ff0))
	for i, f := range ff0 {
		ff[i] = tsFile{ts, f}
	}
	ts.t.Logf("I: get files, type=0x%x count=%d", int(t), len(ff))
	return
}

func (ts *testStorage) GetManifest() (f storage.File, err error) {
	f0, err := ts.Storage.GetManifest()
	if err != nil {
		if !os.IsNotExist(err) {
			ts.t.Errorf("E: get manifest failed: %v", err)
		}
		return
	}
	f = tsFile{ts, f0}
	ts.t.Logf("I: get manifest, num=%d", f.Num())
	return
}

func (ts *testStorage) SetManifest(f storage.File) error {
	tf, ok := f.(tsFile)
	if !ok {
		ts.t.Error("E: set manifest failed: type assertion failed")
		return tsErrInvalidFile
	} else if tf.Type() != storage.TypeManifest {
		ts.t.Errorf("E: set manifest failed: invalid file type: %s", tf.Type())
		return tsErrInvalidFile
	}
	err := ts.Storage.SetManifest(tf.File)
	if err != nil {
		ts.t.Errorf("E: set manifest failed: %v", err)
	} else {
		ts.t.Logf("I: set manifest, num=%d", tf.Num())
	}
	return err
}

func (ts *testStorage) Close() error {
	ts.CloseCheck()
	err := ts.Storage.Close()
	if err != nil {
		ts.t.Errorf("E: closing storage failed: %v", err)
	} else {
		ts.t.Log("I: storage closed")
	}
	if ts.closeFn != nil {
		if err := ts.closeFn(); err != nil {
			ts.t.Errorf("E: close function: %v", err)
		}
	}
	return err
}

func (ts *testStorage) CloseCheck() {
	ts.mu.Lock()
	if len(ts.opens) == 0 {
		ts.t.Log("I: all files are closed")
	} else {
		ts.t.Errorf("E: %d files still open", len(ts.opens))
		for x, writer := range ts.opens {
			num, tt := x>>typeShift, storage.FileType(x)&storage.TypeAll
			ts.t.Errorf("E: * num=%d type=%v writer=%v", num, tt, writer)
		}
	}
	ts.mu.Unlock()
}

func newTestStorage(t *testing.T) *testStorage {
	var stor storage.Storage
	var closeFn func() error
	if tsFS {
		for {
			tsMU.Lock()
			num := tsNum
			tsNum++
			tsMU.Unlock()
			path := filepath.Join(os.TempDir(), fmt.Sprintf("goleveldb-test%d0%d0%d", os.Getuid(), os.Getpid(), num))
			if _, err := os.Stat(path); err != nil {
				stor, err = storage.OpenFile(path)
				if err != nil {
					t.Fatalf("F: cannot create storage: %v", err)
				}
				t.Logf("I: storage created: %s", path)
				closeFn = func() error {
					for _, name := range []string{"LOG.old", "LOG"} {
						f, err := os.Open(filepath.Join(path, name))
						if err != nil {
							continue
						}
						if log, err := ioutil.ReadAll(f); err != nil {
							t.Logf("---------------------- %s ----------------------", name)
							t.Logf("cannot read log: %v", err)
							t.Logf("---------------------- %s ----------------------", name)
						} else if len(log) > 0 {
							t.Logf("---------------------- %s ----------------------\n%s", name, string(log))
							t.Logf("---------------------- %s ----------------------", name)
						}
						f.Close()
					}
					if tsKeepFS {
						return nil
					}
					return os.RemoveAll(path)
				}

				break
			}
		}
	} else {
		stor = storage.NewMemStorage()
	}
	ts := &testStorage{
		t:       t,
		Storage: stor,
		closeFn: closeFn,
		opens:   make(map[uint64]bool),
	}
	ts.cond.L = &ts.mu
	return ts
}
<|endoftext|>


<commit_before>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Package table allows read and write sorted key/value.
package table

import (
	"runtime"
	"strings"

	"github.com/syndtr/goleveldb/leveldb/block"
	"github.com/syndtr/goleveldb/leveldb/cache"
	"github.com/syndtr/goleveldb/leveldb/comparer"
	"github.com/syndtr/goleveldb/leveldb/errors"
	"github.com/syndtr/goleveldb/leveldb/iterator"
	"github.com/syndtr/goleveldb/leveldb/opt"
	"github.com/syndtr/goleveldb/leveldb/storage"
)

// Reader represent a table reader.
type Reader struct {
	r storage.Reader
	o opt.OptionsGetter

	indexBlock  *block.Reader
	filterBlock *block.FilterReader

	dataEnd uint64
	cache   cache.Namespace
}

// NewReader create new initialized table reader.
func NewReader(r storage.Reader, size uint64, o opt.OptionsGetter, cache cache.Namespace) (p *Reader, err error) {
	mb, ib, err := readFooter(r, size)
	if err != nil {
		return
	}

	t := &Reader{r: r, o: o, dataEnd: mb.offset, cache: cache}

	// index block
	buf, err := ib.readAll(r, true)
	if err != nil {
		return
	}
	t.indexBlock, err = block.NewReader(buf, o.GetComparer())
	if err != nil {
		return
	}

	// we will ignore any errors at meta/filter block
	// since it is not essential for operation

	// meta block
	buf, err1 := mb.readAll(r, true)
	if err1 != nil {
		return
	}
	meta, err1 := block.NewReader(buf, comparer.BytesComparer{})
	if err1 != nil {
		return
	}

	// filter block
	iter := meta.NewIterator()
	for iter.Next() {
		key := string(iter.Key())
		if !strings.HasPrefix(key, "filter.") {
			continue
		}
		if filter := o.GetAltFilter(key[7:]); filter != nil {
			fb := new(bInfo)
			_, err1 = fb.decodeFrom(iter.Value())
			if err1 != nil {
				continue
			}

			// now the data block end before filter block start offset
			// instead of meta block start offset
			t.dataEnd = fb.offset

			buf, err1 = fb.readAll(r, true)
			if err1 != nil {
				continue
			}
			t.filterBlock, err1 = block.NewFilterReader(buf, filter)
			if err1 != nil {
				continue
			}
			break
		}
	}

	return t, nil
}

// NewIterator create new iterator over the table.
func (t *Reader) NewIterator(ro opt.ReadOptionsGetter) iterator.Iterator {
	index_iter := &indexIter{t: t, ro: ro}
	t.indexBlock.InitIterator(&index_iter.Iterator)
	return iterator.NewIndexedIterator(index_iter)
}

// Get lookup for given key on the table. Get returns errors.ErrNotFound if
// given key did not exist.
func (t *Reader) Get(key []byte, ro opt.ReadOptionsGetter) (rkey, rvalue []byte, err error) {
	// create an iterator of index block
	index_iter := t.indexBlock.NewIterator()
	if !index_iter.Seek(key) {
		err = index_iter.Error()
		if err == nil {
			err = errors.ErrNotFound
		}
		return
	}

	// decode data block info
	bi := new(bInfo)
	_, err = bi.decodeFrom(index_iter.Value())
	if err != nil {
		return
	}

	// get the data block
	if t.filterBlock == nil || t.filterBlock.KeyMayMatch(uint(bi.offset), key) {
		var it iterator.Iterator
		var cache cache.Object
		it, cache, err = t.getDataIter(bi, ro)
		if err != nil {
			return
		}
		if cache != nil {
			defer cache.Release()
		}

		// seek to key
		if !it.Seek(key) {
			err = it.Error()
			if err == nil {
				err = errors.ErrNotFound
			}
			return
		}
		rkey, rvalue = it.Key(), it.Value()
	} else {
		err = errors.ErrNotFound
	}
	return
}

// ApproximateOffsetOf approximate the offset of given key in bytes.
func (t *Reader) ApproximateOffsetOf(key []byte) uint64 {
	index_iter := t.indexBlock.NewIterator()
	if index_iter.Seek(key) {
		bi := new(bInfo)
		_, err := bi.decodeFrom(index_iter.Value())
		if err == nil {
			return bi.offset
		}
	}
	// block info is corrupted or key is past the last key in the file.
	// Approximate the offset by returning offset of the end of data
	// block (which is right near the end of the file).
	return t.dataEnd
}

func (t *Reader) getBlock(bi *bInfo, ro opt.ReadOptionsGetter) (b *block.Reader, err error) {
	buf, err := bi.readAll(t.r, ro.HasFlag(opt.RFVerifyChecksums))
	if err != nil {
		return
	}
	b, err = block.NewReader(buf, t.o.GetComparer())
	return
}

func (t *Reader) getDataIter(bi *bInfo, ro opt.ReadOptionsGetter) (it *block.Iterator, cache cache.Object, err error) {
	var b *block.Reader

	if t.cache != nil {
		var ok bool
		cache, ok = t.cache.Get(bi.offset, func() (ok bool, value interface{}, charge int, fin func()) {
			if ro.HasFlag(opt.RFDontFillCache) {
				return
			}
			b, err = t.getBlock(bi, ro)
			if err == nil {
				ok = true
				value = b
				charge = int(bi.size)
			}
			return
		})

		if err != nil {
			return
		}

		if !ok {
			b, err = t.getBlock(bi, ro)
			if err != nil {
				return
			}
		} else if b == nil {
			b = cache.Value().(*block.Reader)
		}
	} else {
		b, err = t.getBlock(bi, ro)
		if err != nil {
			return
		}
	}

	it = b.NewIterator()
	return
}

type indexIter struct {
	block.Iterator

	t  *Reader
	ro opt.ReadOptionsGetter
}

func (i *indexIter) Get() (it iterator.Iterator, err error) {
	bi := new(bInfo)
	_, err = bi.decodeFrom(i.Value())
	if err != nil {
		return
	}

	x, cache, err := i.t.getDataIter(bi, i.ro)
	if err != nil {
		return
	}
	if cache != nil {
		runtime.SetFinalizer(x, func(x *block.Iterator) {
			cache.Release()
		})
	}
	return x, nil
}
<commit_msg>Remove naked returns from leveldb/table/reader.go.<commit_after>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Package table allows read and write sorted key/value.
package table

import (
	"runtime"
	"strings"

	"github.com/syndtr/goleveldb/leveldb/block"
	"github.com/syndtr/goleveldb/leveldb/cache"
	"github.com/syndtr/goleveldb/leveldb/comparer"
	"github.com/syndtr/goleveldb/leveldb/errors"
	"github.com/syndtr/goleveldb/leveldb/iterator"
	"github.com/syndtr/goleveldb/leveldb/opt"
	"github.com/syndtr/goleveldb/leveldb/storage"
)

// Reader represent a table reader.
type Reader struct {
	r storage.Reader
	o opt.OptionsGetter

	indexBlock  *block.Reader
	filterBlock *block.FilterReader

	dataEnd uint64
	cache   cache.Namespace
}

// NewReader create new initialized table reader.
func NewReader(r storage.Reader, size uint64, o opt.OptionsGetter, cache cache.Namespace) (*Reader, error) {
	mb, ib, err := readFooter(r, size)
	if err != nil {
		return nil, err
	}

	t := &Reader{r: r, o: o, dataEnd: mb.offset, cache: cache}

	// index block
	buf, err := ib.readAll(r, true)
	if err != nil {
		return nil, err
	}
	t.indexBlock, err = block.NewReader(buf, o.GetComparer())
	if err != nil {
		return nil, err
	}

	// we will ignore any errors at meta/filter block
	// since it is not essential for operation

	// meta block
	buf, err1 := mb.readAll(r, true)
	if err1 != nil {
		return nil, err
	}
	meta, err1 := block.NewReader(buf, comparer.BytesComparer{})
	if err1 != nil {
		return nil, err
	}

	// filter block
	iter := meta.NewIterator()
	for iter.Next() {
		key := string(iter.Key())
		if !strings.HasPrefix(key, "filter.") {
			continue
		}
		if filter := o.GetAltFilter(key[7:]); filter != nil {
			fb := new(bInfo)
			if _, err1 = fb.decodeFrom(iter.Value()); err1 != nil {
				continue
			}

			// now the data block end before filter block start offset
			// instead of meta block start offset
			t.dataEnd = fb.offset

			buf, err1 = fb.readAll(r, true)
			if err1 != nil {
				continue
			}
			t.filterBlock, err1 = block.NewFilterReader(buf, filter)
			if err1 != nil {
				continue
			}
			break
		}
	}

	return t, nil
}

// NewIterator create new iterator over the table.
func (t *Reader) NewIterator(ro opt.ReadOptionsGetter) iterator.Iterator {
	index_iter := &indexIter{t: t, ro: ro}
	t.indexBlock.InitIterator(&index_iter.Iterator)
	return iterator.NewIndexedIterator(index_iter)
}

// Get lookup for given key on the table. Get returns errors.ErrNotFound if
// given key did not exist.
func (t *Reader) Get(key []byte, ro opt.ReadOptionsGetter) (rkey, rvalue []byte, err error) {
	// create an iterator of index block
	index_iter := t.indexBlock.NewIterator()
	if !index_iter.Seek(key) {
		if err = index_iter.Error(); err == nil {
			return nil, nil, errors.ErrNotFound
		}
		return nil, nil, nil
	}

	// decode data block info
	bi := new(bInfo)
	if _, err = bi.decodeFrom(index_iter.Value()); err != nil {
		return nil, nil, err
	}

	// get the data block
	if t.filterBlock == nil || t.filterBlock.KeyMayMatch(uint(bi.offset), key) {
		var it iterator.Iterator
		var cache cache.Object
		it, cache, err = t.getDataIter(bi, ro)
		if err != nil {
			return nil, nil, err
		}
		if cache != nil {
			defer cache.Release()
		}

		// seek to key
		if !it.Seek(key) {
			err = it.Error()
			if err == nil {
				return nil, nil, errors.ErrNotFound
			}
			return nil, nil, err
		}
		rkey, rvalue = it.Key(), it.Value()
	} else {
		return nil, nil, errors.ErrNotFound
	}
	return rkey, rvalue, nil
}

// ApproximateOffsetOf approximate the offset of given key in bytes.
func (t *Reader) ApproximateOffsetOf(key []byte) uint64 {
	index_iter := t.indexBlock.NewIterator()
	if index_iter.Seek(key) {
		bi := new(bInfo)
		_, err := bi.decodeFrom(index_iter.Value())
		if err == nil {
			return bi.offset
		}
	}
	// block info is corrupted or key is past the last key in the file.
	// Approximate the offset by returning offset of the end of data
	// block (which is right near the end of the file).
	return t.dataEnd
}

func (t *Reader) getBlock(bi *bInfo, ro opt.ReadOptionsGetter) (*block.Reader, error) {
	buf, err := bi.readAll(t.r, ro.HasFlag(opt.RFVerifyChecksums))
	if err != nil {
		return nil, err
	}
	return block.NewReader(buf, t.o.GetComparer())
}

func (t *Reader) getDataIter(bi *bInfo, ro opt.ReadOptionsGetter) (it *block.Iterator, cache cache.Object, err error) {
	var b *block.Reader

	if t.cache != nil {
		var ok bool
		cache, ok = t.cache.Get(bi.offset, func() (ok bool, value interface{}, charge int, fin func()) {
			if ro.HasFlag(opt.RFDontFillCache) {
				return ok, value, charge, fin
			}
			b, err = t.getBlock(bi, ro)
			if err == nil {
				ok = true
				value = b
				charge = int(bi.size)
			}
			return ok, value, charge, fin
		})

		if err != nil {
			return nil, nil, err
		}

		if !ok {
			b, err = t.getBlock(bi, ro)
			if err != nil {
				return nil, nil, err
			}
		} else if b == nil {
			b = cache.Value().(*block.Reader)
		}
	} else {
		b, err = t.getBlock(bi, ro)
		if err != nil {
			return nil, nil, err
		}
	}

	return b.NewIterator(), cache, nil
}

type indexIter struct {
	block.Iterator

	t  *Reader
	ro opt.ReadOptionsGetter
}

func (i *indexIter) Get() (iterator.Iterator, error) {
	bi := new(bInfo)
	if _, err := bi.decodeFrom(i.Value()); err != nil {
		return nil, err
	}

	x, cache, err := i.t.getDataIter(bi, i.ro)
	if err != nil {
		return nil, err
	}
	if cache != nil {
		runtime.SetFinalizer(x, func(x *block.Iterator) {
			cache.Release()
		})
	}
	return x, nil
}
<|endoftext|>


<commit_before>package spectrum

type ula_byte_t struct {
	valid bool
	value uint8
}

type ula_attr_t struct {
	valid  bool
	value  uint8
	tstate uint
}

type ULA struct {
	// Frame number
	frame uint

	borderColor byte

	// Whether to discern between [data read by ULA] and [data in memory at the end of a frame].
	// If the value is 'false', then fields 'bitmap' and 'attr' will contain no information.
	// The default value is 'true'.
	accurateEmulation bool

	// Screen bitmap data read by ULA, if they differ from data in memory at the end of a frame.
	// Spectrum y-coordinate.
	bitmap [BytesPerLine * ScreenHeight]ula_byte_t

	// Screen attributes read by ULA, if they differ from data in memory at the end of a frame.
	// Linear y-coordinate.
	attr [BytesPerLine * ScreenHeight]ula_attr_t

	// Whether the 8x8 rectangular screen area was modified during the current frame
	dirtyScreen [ScreenWidth_Attr * ScreenHeight_Attr]bool

	z80    *Z80
	memory MemoryAccessor
	ports  PortAccessor
}

func NewULA() *ULA {
	return &ULA{accurateEmulation: true}
}

func (ula *ULA) init(z80 *Z80, memory MemoryAccessor, ports PortAccessor) {
	ula.z80 = z80
	ula.memory = memory
	ula.ports = ports
}

func (ula *ULA) reset() {
	ula.frame = 0
}

func (ula *ULA) getBorderColor() byte {
	return ula.borderColor
}

func (ula *ULA) setBorderColor(borderColor byte) {
	ula.borderColor = borderColor
}

func (ula *ULA) setEmulationAccuracy(accurateEmulation bool) {
	ula.accurateEmulation = accurateEmulation
}

// This function is called at the beginning of each frame
func (ula *ULA) frame_begin() {
	ula.frame++
	if ula.frame == 1 {
		// The very first frame --> repaint the whole screen
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			ula.dirtyScreen[i] = true
		}
	} else {
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			ula.dirtyScreen[i] = false
		}
	}

	bitmap := &ula.bitmap
	for ofs := uint16(0); ofs < BytesPerLine*ScreenHeight; ofs++ {
		if bitmap[ofs].valid {
			ula.screenBitmapTouch(SCREEN_BASE_ADDR + ofs)
		}

		bitmap[ofs].valid = false
	}

	attr := &ula.attr
	for ofs := uint16(0); ofs < BytesPerLine*ScreenHeight; ofs++ {
		if attr[ofs].valid {
			linearY := (ofs >> BytesPerLine_log2)
			attr_y := (linearY >> 3)
			attr_x := (ofs & 0x001f)
			ula.screenAttrTouch(ATTR_BASE_ADDR + (attr_y << BytesPerLine_log2) + attr_x)
		}

		attr[ofs].valid = false
	}
}

func (ula *ULA) screenBitmapTouch(address uint16) {
	var attr_x, attr_y uint8 = screenAddr_to_attrXY(address)
	ula.dirtyScreen[uint(attr_y)*ScreenWidth_Attr+uint(attr_x)] = true
}

func (ula *ULA) screenAttrTouch(address uint16) {
	ula.dirtyScreen[address-ATTR_BASE_ADDR] = true
}

// Handle a write to an address in range (SCREEN_BASE_ADDR ... SCREEN_BASE_ADDR+0x1800-1)
func (ula *ULA) screenBitmapWrite(address uint16, oldValue byte, newValue byte) {
	if oldValue != newValue {
		ula.screenBitmapTouch(address)

		if ula.accurateEmulation {
			rel_addr := address - SCREEN_BASE_ADDR
			ula_lineStart_tstate := screenline_start_tstates[rel_addr>>BytesPerLine_log2]
			x, _ := screenAddr_to_xy(address)
			ula_tstate := ula_lineStart_tstate + uint(x>>PIXELS_PER_TSTATE_LOG2)
			if ula_tstate <= ula.z80.tstates {
				// Remember the value read by ULA
				ula.bitmap[rel_addr] = ula_byte_t{true, oldValue}
			}
		}
	}
}

// Handle a write to an address in range (ATTR_BASE_ADDR ... ATTR_BASE_ADDR+0x300-1)
func (ula *ULA) screenAttrWrite(address uint16, oldValue byte, newValue byte) {
	if oldValue != newValue {
		ula.screenAttrTouch(address)

		if ula.accurateEmulation {
			CPU := ula.z80

			attr_x := uint(address & 0x001f)
			attr_y := uint((address - ATTR_BASE_ADDR) >> ScreenWidth_Attr_log2)

			x := 8 * attr_x
			y := 8 * attr_y

			ofs := (y << BytesPerLine_log2) + attr_x
			ula_tstate := FIRST_SCREEN_BYTE + y*TSTATES_PER_LINE + (x >> PIXELS_PER_TSTATE_LOG2)

			for i := 0; i < 8; i++ {
				if ula_tstate <= CPU.tstates {
					ula_attr := &ula.attr[ofs]
					if !ula_attr.valid || (ula_tstate > ula_attr.tstate) {
						*ula_attr = ula_attr_t{true, oldValue, CPU.tstates}
					}
					ofs += BytesPerLine
					ula_tstate += TSTATES_PER_LINE
				} else {
					break
				}
			}
		}
	}
}

func (ula *ULA) prepare(display *DisplayInfo) *DisplayData {
	sendDiffOnly := false
	if display.lastFrame != nil {
		sendDiffOnly = true
	}

	var screen DisplayData
	{
		flash := (ula.frame & 0x10) != 0
		flash_previous := ((ula.frame - 1) & 0x10) != 0
		flash_diff := (flash != flash_previous)

		// screen.dirty
		if sendDiffOnly {
			screen.Dirty = ula.dirtyScreen
		} else {
			for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
				screen.Dirty[i] = true
			}
		}

		// Fill screen.bitmap & screen.attr, but only the dirty regions.
		var memory_data *[0x10000]byte = ula.memory.Data()
		ula_bitmap := &ula.bitmap
		ula_attr := &ula.attr
		screen_dirty := &screen.Dirty
		screen_bitmap := &screen.Bitmap
		screen_attr := &screen.Attr
		for attr_y := uint(0); attr_y < ScreenHeight_Attr; attr_y++ {
			attr_y8 := 8 * attr_y

			for attr_x := uint(0); attr_x < ScreenWidth_Attr; attr_x++ {
				attr_ofs := attr_y*ScreenWidth_Attr + attr_x

				// Make sure to send all changed flashing pixels to the DisplayReceiver
				if flash_diff {
					linearY_ofs := (attr_y8 << BytesPerLine_log2) + attr_x

					for y := 0; y < 8; y++ {
						var attr byte
						if !ula_attr[linearY_ofs].valid {
							attr = memory_data[ATTR_BASE_ADDR+attr_ofs]
						} else {
							attr = ula_attr[linearY_ofs].value
						}

						if (attr & 0x80) != 0 {
							screen_dirty[attr_ofs] = true
							break
						}

						linearY_ofs += BytesPerLine
					}
				}

				if !screen_dirty[attr_ofs] {
					continue
				}

				// screen.bitmap
				{
					screen_addr := xy_to_screenAddr(uint8(8*attr_x), uint8(attr_y8))
					linearY_ofs := (attr_y8 << BytesPerLine_log2) + attr_x

					for y := 0; y < 8; y++ {
						if !ula_bitmap[screen_addr-SCREEN_BASE_ADDR].valid {
							screen_bitmap[linearY_ofs] = memory_data[screen_addr]
						} else {
							screen_bitmap[linearY_ofs] = ula_bitmap[screen_addr-SCREEN_BASE_ADDR].value
						}

						screen_addr += 8 * BytesPerLine
						linearY_ofs += BytesPerLine
					}
				}

				// screen.attr
				{
					linearY_ofs := (attr_y8 << BytesPerLine_log2) + attr_x

					for y := 0; y < 8; y++ {
						var attr byte
						if !ula_attr[linearY_ofs].valid {
							attr = memory_data[ATTR_BASE_ADDR+attr_ofs]
						} else {
							attr = ula_attr[linearY_ofs].value
						}

						ink := ((attr & 0x40) >> 3) | (attr & 0x07)
						paper := (attr & 0x78) >> 3

						if flash && ((attr & 0x80) != 0) {
							/* invert flashing attributes */
							ink, paper = paper, ink
						}

						screen_attr[linearY_ofs] = Attr_4bit((ink << 4) | paper)

						linearY_ofs += BytesPerLine
					}
				}
			}
		}

		// screen.borderEvents
		screen.BorderEvents_orNil = ula.ports.getBorderEvents_orNil()
	}

	return &screen
}

func (ula *ULA) sendScreenToDisplay(display *DisplayInfo, completionTime_orNil chan<- int64) {
	displayData := ula.prepare(display)
	displayData.CompletionTime_orNil = completionTime_orNil

	if display.missedChanges != nil {
		display.missedChanges.add(displayData)
		displayData = display.missedChanges
		display.missedChanges = nil
	}

	displayData.CompletionTime_orNil = completionTime_orNil
	displayChannel := display.displayReceiver.GetDisplayDataChannel()

	var nonBlockingSend bool
	select {
	case displayChannel <- displayData:
		nonBlockingSend = true
	default:
		nonBlockingSend = false
	}

	if nonBlockingSend {
		if display.lastFrame == nil {
			display.lastFrame = new(uint)
		}
		*(display.lastFrame) = ula.frame
	} else {
		// Nothing was sent over the 'displayChannel', because the send would block.
		// Avoiding the blocking allows the CPU emulation to proceed when the next tick arrives,
		// instead of waiting for the display backend to receive the previous frame.
		// The 'display.lastFrame' is NOT updated.
		display.numMissedFrames++
		display.missedChanges = displayData
	}
}

// Adds the change-set 'b' to the change-set 'a'.
// This modifies 'a' only, 'b' is left unchanged.
// This is not a commutative operation, the order is significant.
func (a *DisplayData) add(b *DisplayData) {
	a_dirty := &a.Dirty
	a_bitmap := &a.Bitmap
	a_attr := &a.Attr

	b_dirty := &b.Dirty
	b_bitmap := &b.Bitmap
	b_attr := &b.Attr

	for attr_y := uint(0); attr_y < ScreenHeight_Attr; attr_y++ {
		attr_y8 := 8 * attr_y

		for attr_x := uint(0); attr_x < ScreenWidth_Attr; attr_x++ {
			attr_ofs := attr_y*ScreenWidth_Attr + attr_x

			if b_dirty[attr_ofs] {
				a_dirty[attr_ofs] = true

				ofs := (attr_y8 << BytesPerLine_log2) + attr_x
				for y := 0; y < 8; y++ {
					a_bitmap[ofs] = b_bitmap[ofs]
					a_attr[ofs] = b_attr[ofs]
					ofs += BytesPerLine
				}
			}
		}
	}

	a.BorderEvents_orNil = b.BorderEvents_orNil
}
<commit_msg>A very small code optimization in 'ula.go'<commit_after>package spectrum

type ula_byte_t struct {
	valid bool
	value uint8
}

type ula_attr_t struct {
	valid  bool
	value  uint8
	tstate uint
}

type ULA struct {
	// Frame number
	frame uint

	borderColor byte

	// Whether to discern between [data read by ULA] and [data in memory at the end of a frame].
	// If the value is 'false', then fields 'bitmap' and 'attr' will contain no information.
	// The default value is 'true'.
	accurateEmulation bool

	// Screen bitmap data read by ULA, if they differ from data in memory at the end of a frame.
	// Spectrum y-coordinate.
	bitmap [BytesPerLine * ScreenHeight]ula_byte_t

	// Screen attributes read by ULA, if they differ from data in memory at the end of a frame.
	// Linear y-coordinate.
	attr [BytesPerLine * ScreenHeight]ula_attr_t

	// Whether the 8x8 rectangular screen area was modified during the current frame
	dirtyScreen [ScreenWidth_Attr * ScreenHeight_Attr]bool

	z80    *Z80
	memory MemoryAccessor
	ports  PortAccessor
}

func NewULA() *ULA {
	return &ULA{accurateEmulation: true}
}

func (ula *ULA) init(z80 *Z80, memory MemoryAccessor, ports PortAccessor) {
	ula.z80 = z80
	ula.memory = memory
	ula.ports = ports
}

func (ula *ULA) reset() {
	ula.frame = 0
}

func (ula *ULA) getBorderColor() byte {
	return ula.borderColor
}

func (ula *ULA) setBorderColor(borderColor byte) {
	ula.borderColor = borderColor
}

func (ula *ULA) setEmulationAccuracy(accurateEmulation bool) {
	ula.accurateEmulation = accurateEmulation
}

// This function is called at the beginning of each frame
func (ula *ULA) frame_begin() {
	ula.frame++
	if ula.frame == 1 {
		// The very first frame --> repaint the whole screen
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			ula.dirtyScreen[i] = true
		}
	} else {
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			ula.dirtyScreen[i] = false
		}
	}

	bitmap := &ula.bitmap
	for ofs := uint(0); ofs < BytesPerLine*ScreenHeight; ofs++ {
		if bitmap[ofs].valid {
			ula.screenBitmapTouch(uint16(SCREEN_BASE_ADDR + ofs))

			bitmap[ofs].valid = false
		}
	}

	attr := &ula.attr
	for ofs := uint(0); ofs < BytesPerLine*ScreenHeight; ofs++ {
		if attr[ofs].valid {
			linearY := (ofs >> BytesPerLine_log2)
			attr_y := (linearY >> 3)
			attr_x := (ofs & 0x001f)
			ula.screenAttrTouch(uint16(ATTR_BASE_ADDR + (attr_y << BytesPerLine_log2) + attr_x))

			attr[ofs].valid = false
		}
	}
}

func (ula *ULA) screenBitmapTouch(address uint16) {
	var attr_x, attr_y uint8 = screenAddr_to_attrXY(address)
	ula.dirtyScreen[uint(attr_y)*ScreenWidth_Attr+uint(attr_x)] = true
}

func (ula *ULA) screenAttrTouch(address uint16) {
	ula.dirtyScreen[address-ATTR_BASE_ADDR] = true
}

// Handle a write to an address in range (SCREEN_BASE_ADDR ... SCREEN_BASE_ADDR+0x1800-1)
func (ula *ULA) screenBitmapWrite(address uint16, oldValue byte, newValue byte) {
	if oldValue != newValue {
		ula.screenBitmapTouch(address)

		if ula.accurateEmulation {
			rel_addr := address - SCREEN_BASE_ADDR
			ula_lineStart_tstate := screenline_start_tstates[rel_addr>>BytesPerLine_log2]
			x, _ := screenAddr_to_xy(address)
			ula_tstate := ula_lineStart_tstate + uint(x>>PIXELS_PER_TSTATE_LOG2)
			if ula_tstate <= ula.z80.tstates {
				// Remember the value read by ULA
				ula.bitmap[rel_addr] = ula_byte_t{true, oldValue}
			}
		}
	}
}

// Handle a write to an address in range (ATTR_BASE_ADDR ... ATTR_BASE_ADDR+0x300-1)
func (ula *ULA) screenAttrWrite(address uint16, oldValue byte, newValue byte) {
	if oldValue != newValue {
		ula.screenAttrTouch(address)

		if ula.accurateEmulation {
			CPU := ula.z80

			attr_x := uint(address & 0x001f)
			attr_y := uint((address - ATTR_BASE_ADDR) >> ScreenWidth_Attr_log2)

			x := 8 * attr_x
			y := 8 * attr_y

			ofs := (y << BytesPerLine_log2) + attr_x
			ula_tstate := FIRST_SCREEN_BYTE + y*TSTATES_PER_LINE + (x >> PIXELS_PER_TSTATE_LOG2)

			for i := 0; i < 8; i++ {
				if ula_tstate <= CPU.tstates {
					ula_attr := &ula.attr[ofs]
					if !ula_attr.valid || (ula_tstate > ula_attr.tstate) {
						*ula_attr = ula_attr_t{true, oldValue, CPU.tstates}
					}
					ofs += BytesPerLine
					ula_tstate += TSTATES_PER_LINE
				} else {
					break
				}
			}
		}
	}
}

func (ula *ULA) prepare(display *DisplayInfo) *DisplayData {
	sendDiffOnly := false
	if display.lastFrame != nil {
		sendDiffOnly = true
	}

	var screen DisplayData
	{
		flash := (ula.frame & 0x10) != 0
		flash_previous := ((ula.frame - 1) & 0x10) != 0
		flash_diff := (flash != flash_previous)

		// screen.dirty
		if sendDiffOnly {
			screen.Dirty = ula.dirtyScreen
		} else {
			for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
				screen.Dirty[i] = true
			}
		}

		// Fill screen.bitmap & screen.attr, but only the dirty regions.
		var memory_data *[0x10000]byte = ula.memory.Data()
		ula_bitmap := &ula.bitmap
		ula_attr := &ula.attr
		screen_dirty := &screen.Dirty
		screen_bitmap := &screen.Bitmap
		screen_attr := &screen.Attr
		for attr_y := uint(0); attr_y < ScreenHeight_Attr; attr_y++ {
			attr_y8 := 8 * attr_y

			for attr_x := uint(0); attr_x < ScreenWidth_Attr; attr_x++ {
				attr_ofs := attr_y*ScreenWidth_Attr + attr_x

				// Make sure to send all changed flashing pixels to the DisplayReceiver
				if flash_diff {
					linearY_ofs := (attr_y8 << BytesPerLine_log2) + attr_x

					for y := 0; y < 8; y++ {
						var attr byte
						if !ula_attr[linearY_ofs].valid {
							attr = memory_data[ATTR_BASE_ADDR+attr_ofs]
						} else {
							attr = ula_attr[linearY_ofs].value
						}

						if (attr & 0x80) != 0 {
							screen_dirty[attr_ofs] = true
							break
						}

						linearY_ofs += BytesPerLine
					}
				}

				if !screen_dirty[attr_ofs] {
					continue
				}

				// screen.bitmap
				{
					screen_addr := xy_to_screenAddr(uint8(8*attr_x), uint8(attr_y8))
					linearY_ofs := (attr_y8 << BytesPerLine_log2) + attr_x

					for y := 0; y < 8; y++ {
						if !ula_bitmap[screen_addr-SCREEN_BASE_ADDR].valid {
							screen_bitmap[linearY_ofs] = memory_data[screen_addr]
						} else {
							screen_bitmap[linearY_ofs] = ula_bitmap[screen_addr-SCREEN_BASE_ADDR].value
						}

						screen_addr += 8 * BytesPerLine
						linearY_ofs += BytesPerLine
					}
				}

				// screen.attr
				{
					linearY_ofs := (attr_y8 << BytesPerLine_log2) + attr_x

					for y := 0; y < 8; y++ {
						var attr byte
						if !ula_attr[linearY_ofs].valid {
							attr = memory_data[ATTR_BASE_ADDR+attr_ofs]
						} else {
							attr = ula_attr[linearY_ofs].value
						}

						ink := ((attr & 0x40) >> 3) | (attr & 0x07)
						paper := (attr & 0x78) >> 3

						if flash && ((attr & 0x80) != 0) {
							/* invert flashing attributes */
							ink, paper = paper, ink
						}

						screen_attr[linearY_ofs] = Attr_4bit((ink << 4) | paper)

						linearY_ofs += BytesPerLine
					}
				}
			}
		}

		// screen.borderEvents
		screen.BorderEvents_orNil = ula.ports.getBorderEvents_orNil()
	}

	return &screen
}

func (ula *ULA) sendScreenToDisplay(display *DisplayInfo, completionTime_orNil chan<- int64) {
	displayData := ula.prepare(display)
	displayData.CompletionTime_orNil = completionTime_orNil

	if display.missedChanges != nil {
		display.missedChanges.add(displayData)
		displayData = display.missedChanges
		display.missedChanges = nil
	}

	displayData.CompletionTime_orNil = completionTime_orNil
	displayChannel := display.displayReceiver.GetDisplayDataChannel()

	var nonBlockingSend bool
	select {
	case displayChannel <- displayData:
		nonBlockingSend = true
	default:
		nonBlockingSend = false
	}

	if nonBlockingSend {
		if display.lastFrame == nil {
			display.lastFrame = new(uint)
		}
		*(display.lastFrame) = ula.frame
	} else {
		// Nothing was sent over the 'displayChannel', because the send would block.
		// Avoiding the blocking allows the CPU emulation to proceed when the next tick arrives,
		// instead of waiting for the display backend to receive the previous frame.
		// The 'display.lastFrame' is NOT updated.
		display.numMissedFrames++
		display.missedChanges = displayData
	}
}

// Adds the change-set 'b' to the change-set 'a'.
// This modifies 'a' only, 'b' is left unchanged.
// This is not a commutative operation, the order is significant.
func (a *DisplayData) add(b *DisplayData) {
	a_dirty := &a.Dirty
	a_bitmap := &a.Bitmap
	a_attr := &a.Attr

	b_dirty := &b.Dirty
	b_bitmap := &b.Bitmap
	b_attr := &b.Attr

	for attr_y := uint(0); attr_y < ScreenHeight_Attr; attr_y++ {
		attr_y8 := 8 * attr_y

		for attr_x := uint(0); attr_x < ScreenWidth_Attr; attr_x++ {
			attr_ofs := attr_y*ScreenWidth_Attr + attr_x

			if b_dirty[attr_ofs] {
				a_dirty[attr_ofs] = true

				ofs := (attr_y8 << BytesPerLine_log2) + attr_x
				for y := 0; y < 8; y++ {
					a_bitmap[ofs] = b_bitmap[ofs]
					a_attr[ofs] = b_attr[ofs]
					ofs += BytesPerLine
				}
			}
		}
	}

	a.BorderEvents_orNil = b.BorderEvents_orNil
}
<|endoftext|>


<commit_before>//Author: Gary Connelly
//date 30/09/2017

//adapted from https://gist.github.com/abesto/3476594

package main

import (
	"fmt"
)

func main() {
  var yourNumber float64
  fmt.Println("Enter your number:")
  fmt.Scanf("%f\n", &yourNumber)
	fmt.Println(Sqrt(yourNumber))

}

// Newton's method
func zNext(z, x float64) float64 {
	return z - (z*z-x)/(2*z)
}

func Sqrt(x float64) float64 {
	z := zNext(2, x)
	for zn, delta := z, z; delta > 0.00001; z = zn {
		zn = zNext(z, x)
		delta = z - zn
	}
	return z
}<commit_msg>adding comments<commit_after>//Author: Gary Connelly
//date 30/09/2017

//adapted from https://gist.github.com/abesto/3476594

package main

import (
	"fmt"
)

//main method
func main() {
  var yourNumber float64
  //take in user input
  fmt.Println("Enter your number:")
  fmt.Scanf("%f\n", &yourNumber)
  //call square root method for the input number
	fmt.Println(Sqrt(yourNumber))

}

// Newton's method
func zNext(z, x float64) float64 {
	return z - (z*z-x)/(2*z)
}

func Sqrt(x float64) float64 {
	z := zNext(2, x)
	for zn, delta := z, z; delta > 0.00001; z = zn {
		zn = zNext(z, x)
		delta = z - zn
	}
	return z
}<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"github.com/go-playground/validator"
)

func goodHandler(w http.ResponseWriter, req *http.Request) {
	validate := validator.New()
	target := req.FormValue("target")
	if validate.Var(target, "alphanum")
	// GOOD: `target` is alphanumeric
	resp, err := http.Get("https://example.com/current_api/" + target)
	if err != nil {
		// error handling
	}

	// process request response
	use(resp)
}
<commit_msg>Fix qhelp good example<commit_after>package main

import (
	"github.com/go-playground/validator"
	"net/http"
)

func goodHandler(w http.ResponseWriter, req *http.Request) {
	validate := validator.New()
	target := req.FormValue("target")
	if validate.Var(target, "alphanum") == nil {
		// GOOD: `target` is alphanumeric
		resp, err := http.Get("https://example.com/current_api/" + target)
		if err != nil {
			// error handling
		}
		// process request response
		use(resp)
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 CoreOS, Inc.
//
// 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 omaha

import (
	"net/http"
)

type trivialUpdater struct {
	UpdaterStub
	Update
}

func (tu *trivialUpdater) CheckUpdate(req *Request, app *AppRequest) (*Update, error) {
	return &tu.Update, nil
}

type trivialHandler struct {
	Path string
}

func (th *trivialHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if th.Path == "" {
		http.NotFound(w, r)
	}
	http.ServeFile(w, r, th.Path)
}

type TrivialServer struct {
	*Server
	th trivialHandler
}

func NewTrivialServer(addr string) (*TrivialServer, error) {
	s, err := NewServer(addr, &UpdaterStub{})
	if err != nil {
		return nil, err
	}
	ts := TrivialServer{Server: s}
	ts.Mux.Handle("/packages/update.gz", &ts.th)
	return &ts, nil
}

func (ts *TrivialServer) SetPackage(path string) error {
	tu := trivialUpdater{
		Update: Update{
			URL: URL{CodeBase: "/packages/"},
		},
	}

	pkg, err := tu.Manifest.AddPackageFromPath(path)
	if err != nil {
		return err
	}
	pkg.Name = "update.gz"
	act := tu.Manifest.AddAction("postinstall")
	act.Sha256 = pkg.Sha256

	ts.th.Path = path
	ts.Updater = &tu
	return nil
}
<commit_msg>network/omaha: disable update_engine's backoff timer for testing<commit_after>// Copyright 2016 CoreOS, Inc.
//
// 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 omaha

import (
	"net/http"
)

type trivialUpdater struct {
	UpdaterStub
	Update
}

func (tu *trivialUpdater) CheckUpdate(req *Request, app *AppRequest) (*Update, error) {
	return &tu.Update, nil
}

type trivialHandler struct {
	Path string
}

func (th *trivialHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if th.Path == "" {
		http.NotFound(w, r)
	}
	http.ServeFile(w, r, th.Path)
}

type TrivialServer struct {
	*Server
	th trivialHandler
}

func NewTrivialServer(addr string) (*TrivialServer, error) {
	s, err := NewServer(addr, &UpdaterStub{})
	if err != nil {
		return nil, err
	}
	ts := TrivialServer{Server: s}
	ts.Mux.Handle("/packages/update.gz", &ts.th)
	return &ts, nil
}

func (ts *TrivialServer) SetPackage(path string) error {
	tu := trivialUpdater{
		Update: Update{
			URL: URL{CodeBase: "/packages/"},
		},
	}

	pkg, err := tu.Manifest.AddPackageFromPath(path)
	if err != nil {
		return err
	}
	pkg.Name = "update.gz"
	act := tu.Manifest.AddAction("postinstall")
	act.DisablePayloadBackoff = true
	act.Sha256 = pkg.Sha256

	ts.th.Path = path
	ts.Updater = &tu
	return nil
}
<|endoftext|>


<commit_before>package xmpp

import (
	"bytes"
	"encoding/xml"
	"errors"
	"fmt"
	"net"
	"strings"
)

type Client struct {
	// Store user defined options
	options Options
	// Session gather data that can be accessed by users of this library
	Session *Session
	// TCP level connection / can be replace by a TLS session after starttls
	conn net.Conn
}

/*
Setting up the client / Checking the parameters
*/

// TODO: better options check
func NewClient(options Options) (c *Client, err error) {
	// TODO: If option address is nil, use the Jid domain to compose the address
	if options.Address, err = checkAddress(options.Address); err != nil {
		return
	}

	if options.Password == "" {
		err = errors.New("missing password")
		return
	}

	c = new(Client)
	c.options = options

	// Parse JID
	if c.options.parsedJid, err = NewJid(c.options.Jid); err != nil {
		return
	}

	return
}

func checkAddress(addr string) (string, error) {
	var err error
	hostport := strings.Split(addr, ":")
	if len(hostport) > 2 {
		err = errors.New("too many colons in xmpp server address")
		return addr, err
	}

	// Address is composed of two parts, we are good
	if len(hostport) == 2 && hostport[1] != "" {
		return addr, err
	}

	// Port was not passed, we append XMPP default port:
	return strings.Join([]string{hostport[0], "5222"}, ":"), err
}

// NewClient creates a new connection to a host given as "hostname" or "hostname:port".
// If host is not specified, the  DNS SRV should be used to find the host from the domainpart of the JID.
// Default the port to 5222.
func (c *Client) Connect() (*Session, error) {
	var tcpconn net.Conn
	var err error
	if tcpconn, err = net.Dial("tcp", c.options.Address); err != nil {
		return nil, err
	}

	c.conn = tcpconn
	if c.conn, c.Session, err = NewSession(c.conn, c.options); err != nil {
		return c.Session, err
	}

	// We're connected and can now receive and send messages.
	//fmt.Fprintf(client.conn, "<presence xml:lang='en'><show>%s</show><status>%s</status></presence>", "chat", "Online")
	fmt.Fprintf(c.Session.socketProxy, "<presence/>")

	return c.Session, err
}

func (c *Client) recv(receiver chan<- interface{}) (err error) {
	for {
		_, val, err := next(c.Session.decoder)
		if err != nil {
			return err
		}
		receiver <- val
		val = nil
	}
	panic("unreachable")
}

// Channel allow client to receive / dispatch packets in for range loop
func (c *Client) Recv() <-chan interface{} {
	ch := make(chan interface{})
	go c.recv(ch)
	return ch
}

// Send sends message text.
func (c *Client) Send(packet string) error {
	fmt.Fprintf(c.Session.socketProxy, packet)
	return nil
}

func xmlEscape(s string) string {
	var b bytes.Buffer
	xml.Escape(&b, []byte(s))
	return b.String()
}
<commit_msg>Add TODO comment for later fix<commit_after>package xmpp

import (
	"bytes"
	"encoding/xml"
	"errors"
	"fmt"
	"net"
	"strings"
)

type Client struct {
	// Store user defined options
	options Options
	// Session gather data that can be accessed by users of this library
	Session *Session
	// TCP level connection / can be replace by a TLS session after starttls
	conn net.Conn
}

/*
Setting up the client / Checking the parameters
*/

// TODO: better options check
func NewClient(options Options) (c *Client, err error) {
	// TODO: If option address is nil, use the Jid domain to compose the address
	if options.Address, err = checkAddress(options.Address); err != nil {
		return
	}

	if options.Password == "" {
		err = errors.New("missing password")
		return
	}

	c = new(Client)
	c.options = options

	// Parse JID
	if c.options.parsedJid, err = NewJid(c.options.Jid); err != nil {
		return
	}

	return
}

func checkAddress(addr string) (string, error) {
	var err error
	hostport := strings.Split(addr, ":")
	if len(hostport) > 2 {
		err = errors.New("too many colons in xmpp server address")
		return addr, err
	}

	// Address is composed of two parts, we are good
	if len(hostport) == 2 && hostport[1] != "" {
		return addr, err
	}

	// Port was not passed, we append XMPP default port:
	return strings.Join([]string{hostport[0], "5222"}, ":"), err
}

// NewClient creates a new connection to a host given as "hostname" or "hostname:port".
// If host is not specified, the  DNS SRV should be used to find the host from the domainpart of the JID.
// Default the port to 5222.
func (c *Client) Connect() (*Session, error) {
	var tcpconn net.Conn
	var err error
	if tcpconn, err = net.Dial("tcp", c.options.Address); err != nil {
		return nil, err
	}

	c.conn = tcpconn
	if c.conn, c.Session, err = NewSession(c.conn, c.options); err != nil {
		return c.Session, err
	}

	// We're connected and can now receive and send messages.
	//fmt.Fprintf(client.conn, "<presence xml:lang='en'><show>%s</show><status>%s</status></presence>", "chat", "Online")
	// TODO: Do we always want to send initial presence automatically ?
	// Do we need an option to avoid that or do we rely on client to send the presence itself ?
	fmt.Fprintf(c.Session.socketProxy, "<presence/>")

	return c.Session, err
}

func (c *Client) recv(receiver chan<- interface{}) (err error) {
	for {
		_, val, err := next(c.Session.decoder)
		if err != nil {
			return err
		}
		receiver <- val
		val = nil
	}
	panic("unreachable")
}

// Channel allow client to receive / dispatch packets in for range loop
func (c *Client) Recv() <-chan interface{} {
	ch := make(chan interface{})
	go c.recv(ch)
	return ch
}

// Send sends message text.
func (c *Client) Send(packet string) error {
	fmt.Fprintf(c.Session.socketProxy, packet)
	return nil
}

func xmlEscape(s string) string {
	var b bytes.Buffer
	xml.Escape(&b, []byte(s))
	return b.String()
}
<|endoftext|>


<commit_before>package resources

import (
	"errors"
	"log"

	"k8s.io/kubernetes/pkg/apis/extensions"
	"k8s.io/kubernetes/pkg/client/unversioned"

	"github.com/Mirantis/k8s-AppController/client"
	"github.com/Mirantis/k8s-AppController/interfaces"
)

//DaemonSet is wrapper for K8s DaemonSet object
type DaemonSet struct {
	DaemonSet *extensions.DaemonSet
	Client    unversioned.DaemonSetInterface
}

func daemonSetKey(name string) string {
	return "daemonset/" + name
}

func daemonSetStatus(d unversioned.DaemonSetInterface, name string) (string, error) {
	daemonSet, err := d.Get(name)
	if err != nil {
		return "error", err
	}
	if daemonSet.Status.CurrentNumberScheduled == daemonSet.Status.DesiredNumberScheduled {
		return "ready", nil
	}
	return "not ready", nil
}

//UpdateMeta does nothing for now
func (d DaemonSet) UpdateMeta(meta map[string]string) error {
	return nil
}

//Key return DaemonSet key
func (d DaemonSet) Key() string {
	return daemonSetKey(d.DaemonSet.Name)
}

// Status returns DaemonSet status as a string "ready" means that its dependencies can be created
func (d DaemonSet) Status(meta map[string]string) (string, error) {
	return daemonSetStatus(d.Client, d.DaemonSet.Name)
}

//Create looks for DaemonSet in K8s and creates it if not present
func (d DaemonSet) Create() error {
	log.Println("Looking for daemonset", d.DaemonSet.Name)
	status, err := d.Status(nil)

	if err == nil {
		log.Printf("Found daemonset %s, status: %s", d.DaemonSet.Name, status)
		log.Println("Skipping creation of daemonset", d.DaemonSet.Name)
	}
	log.Println("Creating daemonset", d.DaemonSet.Name)
	d.DaemonSet, err = d.Client.Create(d.DaemonSet)
	return err
}

// Delete deletes DaemonSet from the cluster
func (d DaemonSet) Delete() error {
	return d.Client.Delete(d.DaemonSet.Name)
}

// NameMatches gets resource definition and a name and checks if
// the DaemonSet part of resource definition has matching name.
func (d DaemonSet) NameMatches(def client.ResourceDefinition, name string) bool {
	return def.DaemonSet != nil && def.DaemonSet.Name == name
}

// New returns new DaemonSet based on resource definition
func (d DaemonSet) New(def client.ResourceDefinition, c client.Interface) interfaces.Resource {
	return NewDaemonSet(def.DaemonSet, c.DaemonSets())
}

// NewExisting returns new ExistingDaemonSet based on resource definition
func (d DaemonSet) NewExisting(name string, c client.Interface) interfaces.Resource {
	return NewExistingDaemonSet(name, c.DaemonSets())
}

//NewDaemonSet is a constructor
func NewDaemonSet(daemonset *extensions.DaemonSet, client unversioned.DaemonSetInterface) DaemonSet {
	return DaemonSet{DaemonSet: daemonset, Client: client}
}

//ExistingDaemonSet is a wrapper for K8s DaemonSet object which is deployed on a cluster before AppController
type ExistingDaemonSet struct {
	Name   string
	Client unversioned.DaemonSetInterface
	DaemonSet
}

//UpdateMeta does nothing at the moment
func (d ExistingDaemonSet) UpdateMeta(meta map[string]string) error {
	return nil
}

//Key returns DaemonSet name
func (d ExistingDaemonSet) Key() string {
	return daemonSetKey(d.Name)
}

// Status returns DaemonSet status as a string "ready" means that its dependencies can be created
func (d ExistingDaemonSet) Status(meta map[string]string) (string, error) {
	return daemonSetStatus(d.Client, d.Name)
}

//Create looks for existing DaemonSet and returns error if there is no such DaemonSet
func (d ExistingDaemonSet) Create() error {
	log.Println("Looking for daemonset", d.Name)
	status, err := d.Status(nil)

	if err == nil {
		log.Printf("Found daemonset %s, status: %s", d.Name, status)
		return nil
	}

	log.Fatalf("DaemonSet %s not found", d.Name)
	return errors.New("DaemonSet not found")
}

//NewExistingDaemonSet is a constructor
func NewExistingDaemonSet(name string, client unversioned.DaemonSetInterface) ExistingDaemonSet {
	return ExistingDaemonSet{Name: name, Client: client}
}
<commit_msg>Remove obsolete method from daemonset<commit_after>package resources

import (
	"errors"
	"log"

	"k8s.io/kubernetes/pkg/apis/extensions"
	"k8s.io/kubernetes/pkg/client/unversioned"

	"github.com/Mirantis/k8s-AppController/client"
	"github.com/Mirantis/k8s-AppController/interfaces"
)

//DaemonSet is wrapper for K8s DaemonSet object
type DaemonSet struct {
	DaemonSet *extensions.DaemonSet
	Client    unversioned.DaemonSetInterface
}

func daemonSetKey(name string) string {
	return "daemonset/" + name
}

func daemonSetStatus(d unversioned.DaemonSetInterface, name string) (string, error) {
	daemonSet, err := d.Get(name)
	if err != nil {
		return "error", err
	}
	if daemonSet.Status.CurrentNumberScheduled == daemonSet.Status.DesiredNumberScheduled {
		return "ready", nil
	}
	return "not ready", nil
}

//Key return DaemonSet key
func (d DaemonSet) Key() string {
	return daemonSetKey(d.DaemonSet.Name)
}

// Status returns DaemonSet status as a string "ready" means that its dependencies can be created
func (d DaemonSet) Status(meta map[string]string) (string, error) {
	return daemonSetStatus(d.Client, d.DaemonSet.Name)
}

//Create looks for DaemonSet in K8s and creates it if not present
func (d DaemonSet) Create() error {
	log.Println("Looking for daemonset", d.DaemonSet.Name)
	status, err := d.Status(nil)

	if err == nil {
		log.Printf("Found daemonset %s, status: %s", d.DaemonSet.Name, status)
		log.Println("Skipping creation of daemonset", d.DaemonSet.Name)
	}
	log.Println("Creating daemonset", d.DaemonSet.Name)
	d.DaemonSet, err = d.Client.Create(d.DaemonSet)
	return err
}

// Delete deletes DaemonSet from the cluster
func (d DaemonSet) Delete() error {
	return d.Client.Delete(d.DaemonSet.Name)
}

// NameMatches gets resource definition and a name and checks if
// the DaemonSet part of resource definition has matching name.
func (d DaemonSet) NameMatches(def client.ResourceDefinition, name string) bool {
	return def.DaemonSet != nil && def.DaemonSet.Name == name
}

// New returns new DaemonSet based on resource definition
func (d DaemonSet) New(def client.ResourceDefinition, c client.Interface) interfaces.Resource {
	return NewDaemonSet(def.DaemonSet, c.DaemonSets())
}

// NewExisting returns new ExistingDaemonSet based on resource definition
func (d DaemonSet) NewExisting(name string, c client.Interface) interfaces.Resource {
	return NewExistingDaemonSet(name, c.DaemonSets())
}

//NewDaemonSet is a constructor
func NewDaemonSet(daemonset *extensions.DaemonSet, client unversioned.DaemonSetInterface) DaemonSet {
	return DaemonSet{DaemonSet: daemonset, Client: client}
}

//ExistingDaemonSet is a wrapper for K8s DaemonSet object which is deployed on a cluster before AppController
type ExistingDaemonSet struct {
	Name   string
	Client unversioned.DaemonSetInterface
	DaemonSet
}

//Key returns DaemonSet name
func (d ExistingDaemonSet) Key() string {
	return daemonSetKey(d.Name)
}

// Status returns DaemonSet status as a string "ready" means that its dependencies can be created
func (d ExistingDaemonSet) Status(meta map[string]string) (string, error) {
	return daemonSetStatus(d.Client, d.Name)
}

//Create looks for existing DaemonSet and returns error if there is no such DaemonSet
func (d ExistingDaemonSet) Create() error {
	log.Println("Looking for daemonset", d.Name)
	status, err := d.Status(nil)

	if err == nil {
		log.Printf("Found daemonset %s, status: %s", d.Name, status)
		return nil
	}

	log.Fatalf("DaemonSet %s not found", d.Name)
	return errors.New("DaemonSet not found")
}

//NewExistingDaemonSet is a constructor
func NewExistingDaemonSet(name string, client unversioned.DaemonSetInterface) ExistingDaemonSet {
	return ExistingDaemonSet{Name: name, Client: client}
}
<|endoftext|>


<commit_before>package resources

import (
	"fmt"
	"github.com/SudoQ/crisp/storage"
	"github.com/gorilla/mux"
	"net/http"
	"log"
)

type Manager struct {
	cache *storage.Store
}

func New(store *storage.Store) *Manager {
	return &Manager{
		cache: store,
	}
}

func (this *Manager) Run(rawport string) {
	r := mux.NewRouter()
	r.HandleFunc("/", this.HomeHandler)
	r.HandleFunc("/info", this.InfoHandler)
	r.HandleFunc("/cache.json", this.CacheHandler)
	port := fmt.Sprintf(":%s", rawport)
	http.ListenAndServe(port, r)
}

func (this *Manager) HomeHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	latestItem, err := this.cache.Get()
	if err != nil {
		log.Print(err)
		w.WriteHeader(404)
		return
	}
	w.Write(latestItem.Payload)
}

func (this *Manager) Info() string {
	return fmt.Sprintf("Crisp API caching service v0.1")
}

func (this *Manager) InfoHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(200)
	w.Write([]byte(this.Info()))
}

func (this *Manager) CacheHandler(w http.ResponseWriter, r *http.Request) {
	latestItem, err := this.cache.Get()
	if err != nil {
		log.Println(err)
		w.WriteHeader(404)
		return
	}

	response, err := latestItem.JSON()
	if err != nil {
		log.Println(err)
		w.WriteHeader(404)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	w.Write(response)
}
<commit_msg>Go fmt<commit_after>package resources

import (
	"fmt"
	"github.com/SudoQ/crisp/storage"
	"github.com/gorilla/mux"
	"log"
	"net/http"
)

type Manager struct {
	cache *storage.Store
}

func New(store *storage.Store) *Manager {
	return &Manager{
		cache: store,
	}
}

func (this *Manager) Run(rawport string) {
	r := mux.NewRouter()
	r.HandleFunc("/", this.HomeHandler)
	r.HandleFunc("/info", this.InfoHandler)
	r.HandleFunc("/cache.json", this.CacheHandler)
	port := fmt.Sprintf(":%s", rawport)
	http.ListenAndServe(port, r)
}

func (this *Manager) HomeHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	latestItem, err := this.cache.Get()
	if err != nil {
		log.Print(err)
		w.WriteHeader(404)
		return
	}
	w.Write(latestItem.Payload)
}

func (this *Manager) Info() string {
	return fmt.Sprintf("Crisp API caching service v0.1")
}

func (this *Manager) InfoHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(200)
	w.Write([]byte(this.Info()))
}

func (this *Manager) CacheHandler(w http.ResponseWriter, r *http.Request) {
	latestItem, err := this.cache.Get()
	if err != nil {
		log.Println(err)
		w.WriteHeader(404)
		return
	}

	response, err := latestItem.JSON()
	if err != nil {
		log.Println(err)
		w.WriteHeader(404)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	w.Write(response)
}
<|endoftext|>