Remove does code from Godeps

We have some code in Godeps/files which is completely unused. Delete it.
This commit is contained in:
Eric Paris 2015-08-03 14:16:04 -04:00
parent 67dbc4c6a6
commit 40c98735fb
18 changed files with 0 additions and 1193 deletions

View File

@ -1,10 +0,0 @@
# This is the official list of authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.
# Names should be added to this file as
# Name or Organization <email address>
# The email address is not required for organizations.
# Please keep the list sorted.
Google Inc.

View File

@ -1,46 +0,0 @@
# This is the official list of people who can contribute
# (and typically have contributed) code to the repository.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# The submission process automatically checks to make sure
# that people submitting code are listed in this file (by email address).
#
# Names should be added to this file only after verifying that
# the individual or the individual's organization has agreed to
# the appropriate Contributor License Agreement, found here:
#
# http://code.google.com/legal/individual-cla-v1.0.html
# http://code.google.com/legal/corporate-cla-v1.0.html
#
# The agreement for individuals can be filled out on the web.
#
# When adding J Random Contributor's name to this file,
# either J's name or J's organization's name should be
# added to the AUTHORS file, depending on whether the
# individual or corporate CLA was used.
# Names should be added to this file like so:
# Name <email address>
#
# An entry with two email addresses specifies that the
# first address should be used in the submit logs and
# that the second address should be recognized as the
# same person when interacting with Rietveld.
# Please keep the list sorted.
Alain Vongsouvanhalainv <alainv@google.com>
Andrew Gerrand <adg@golang.org>
Brad Fitzpatrick <bradfitz@golang.org>
Francesc Campoy <campoy@golang.org>
Garrick Evans <garrick@google.com>
Glenn Lewis <gmlewis@google.com>
Ivan Krasin <krasin@golang.org>
Jason Hall <jasonhall@google.com>
Johan Euphrosine <proppy@google.com>
Kostik Shtoyk <kostik@google.com>
Nick Craig-Wood <nickcw@gmail.com>
Scott Van Woudenberg <scottvw@google.com>
Takashi Matsuo <tmatsuo@google.com>

View File

@ -1,27 +0,0 @@
Copyright (c) 2011 Google Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,9 +0,0 @@
all:
go install code.google.com/p/google-api-go-client/googleapi
go install code.google.com/p/google-api-go-client/google-api-go-generator
$(GOPATH)/bin/google-api-go-generator -cache=false -install -api=*
cached:
go install code.google.com/p/google-api-go-client/googleapi
go install code.google.com/p/google-api-go-client/google-api-go-generator
$(GOPATH)/bin/google-api-go-generator -cache=true -install -api=*

View File

@ -1,13 +0,0 @@
Discovery Service:
http://code.google.com/apis/discovery/
http://code.google.com/apis/discovery/v1/reference.html
The "type" key:
http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
The "format" key:
http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.23
http://code.google.com/apis/discovery/v1/reference.html#parameter-format-summary
Google JSON format docs:
http://google-styleguide.googlecode.com/svn/trunk/jsoncstyleguide.xml

View File

@ -1,10 +0,0 @@
Most of this project is auto-generated.
The notable directories which are not auto-generated:
google-api-go-generator/ -- the generator itself
google-api/ -- shared common code, used by auto-generated code
examples/ -- sample code
When changing the generator, re-compile all APIs and submit the
modified APIs in the same CL as the generator changes itself.

View File

@ -1,2 +0,0 @@
Moved to:
http://code.google.com/p/google-api-go-client/issues/

View File

@ -1,121 +0,0 @@
// +build example-exec
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 main
import (
"flag"
"fmt"
exec "github.com/mesos/mesos-go/executor"
mesos "github.com/mesos/mesos-go/mesosproto"
)
type exampleExecutor struct {
tasksLaunched int
}
func newExampleExecutor() *exampleExecutor {
return &exampleExecutor{tasksLaunched: 0}
}
func (exec *exampleExecutor) Registered(driver exec.ExecutorDriver, execInfo *mesos.ExecutorInfo, fwinfo *mesos.FrameworkInfo, slaveInfo *mesos.SlaveInfo) {
fmt.Println("Registered Executor on slave ", slaveInfo.GetHostname())
}
func (exec *exampleExecutor) Reregistered(driver exec.ExecutorDriver, slaveInfo *mesos.SlaveInfo) {
fmt.Println("Re-registered Executor on slave ", slaveInfo.GetHostname())
}
func (exec *exampleExecutor) Disconnected(exec.ExecutorDriver) {
fmt.Println("Executor disconnected.")
}
func (exec *exampleExecutor) LaunchTask(driver exec.ExecutorDriver, taskInfo *mesos.TaskInfo) {
fmt.Println("Launching task", taskInfo.GetName(), "with command", taskInfo.Command.GetValue())
runStatus := &mesos.TaskStatus{
TaskId: taskInfo.GetTaskId(),
State: mesos.TaskState_TASK_RUNNING.Enum(),
}
_, err := driver.SendStatusUpdate(runStatus)
if err != nil {
fmt.Println("Got error", err)
}
exec.tasksLaunched++
fmt.Println("Total tasks launched ", exec.tasksLaunched)
//
// this is where one would perform the requested task
//
// finish task
fmt.Println("Finishing task", taskInfo.GetName())
finStatus := &mesos.TaskStatus{
TaskId: taskInfo.GetTaskId(),
State: mesos.TaskState_TASK_FINISHED.Enum(),
}
_, err = driver.SendStatusUpdate(finStatus)
if err != nil {
fmt.Println("Got error", err)
}
fmt.Println("Task finished", taskInfo.GetName())
}
func (exec *exampleExecutor) KillTask(exec.ExecutorDriver, *mesos.TaskID) {
fmt.Println("Kill task")
}
func (exec *exampleExecutor) FrameworkMessage(driver exec.ExecutorDriver, msg string) {
fmt.Println("Got framework message: ", msg)
}
func (exec *exampleExecutor) Shutdown(exec.ExecutorDriver) {
fmt.Println("Shutting down the executor")
}
func (exec *exampleExecutor) Error(driver exec.ExecutorDriver, err string) {
fmt.Println("Got error message:", err)
}
// -------------------------- func inits () ----------------- //
func init() {
flag.Parse()
}
func main() {
fmt.Println("Starting Example Executor (Go)")
dconfig := exec.DriverConfig{
Executor: newExampleExecutor(),
}
driver, err := exec.NewMesosExecutorDriver(dconfig)
if err != nil {
fmt.Println("Unable to create a ExecutorDriver ", err.Error())
}
_, err = driver.Start()
if err != nil {
fmt.Println("Got error:", err)
return
}
fmt.Println("Executor process has started and running.")
driver.Join()
}

View File

@ -1,294 +0,0 @@
// +build example-sched
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 main
import (
"flag"
"fmt"
"io/ioutil"
"net"
"net/http"
"strconv"
"strings"
"github.com/gogo/protobuf/proto"
log "github.com/golang/glog"
"github.com/mesos/mesos-go/auth"
"github.com/mesos/mesos-go/auth/sasl"
"github.com/mesos/mesos-go/auth/sasl/mech"
mesos "github.com/mesos/mesos-go/mesosproto"
util "github.com/mesos/mesos-go/mesosutil"
sched "github.com/mesos/mesos-go/scheduler"
"golang.org/x/net/context"
)
const (
CPUS_PER_TASK = 1
MEM_PER_TASK = 128
defaultArtifactPort = 12345
)
var (
address = flag.String("address", "127.0.0.1", "Binding address for artifact server")
artifactPort = flag.Int("artifactPort", defaultArtifactPort, "Binding port for artifact server")
authProvider = flag.String("mesos_authentication_provider", sasl.ProviderName,
fmt.Sprintf("Authentication provider to use, default is SASL that supports mechanisms: %+v", mech.ListSupported()))
master = flag.String("master", "127.0.0.1:5050", "Master address <ip:port>")
executorPath = flag.String("executor", "./example_executor", "Path to test executor")
taskCount = flag.String("task-count", "5", "Total task count to run.")
mesosAuthPrincipal = flag.String("mesos_authentication_principal", "", "Mesos authentication principal.")
mesosAuthSecretFile = flag.String("mesos_authentication_secret_file", "", "Mesos authentication secret file.")
)
type ExampleScheduler struct {
executor *mesos.ExecutorInfo
tasksLaunched int
tasksFinished int
totalTasks int
}
func newExampleScheduler(exec *mesos.ExecutorInfo) *ExampleScheduler {
total, err := strconv.Atoi(*taskCount)
if err != nil {
total = 5
}
return &ExampleScheduler{
executor: exec,
tasksLaunched: 0,
tasksFinished: 0,
totalTasks: total,
}
}
func (sched *ExampleScheduler) Registered(driver sched.SchedulerDriver, frameworkId *mesos.FrameworkID, masterInfo *mesos.MasterInfo) {
log.Infoln("Framework Registered with Master ", masterInfo)
}
func (sched *ExampleScheduler) Reregistered(driver sched.SchedulerDriver, masterInfo *mesos.MasterInfo) {
log.Infoln("Framework Re-Registered with Master ", masterInfo)
}
func (sched *ExampleScheduler) Disconnected(sched.SchedulerDriver) {}
func (sched *ExampleScheduler) ResourceOffers(driver sched.SchedulerDriver, offers []*mesos.Offer) {
for _, offer := range offers {
cpuResources := util.FilterResources(offer.Resources, func(res *mesos.Resource) bool {
return res.GetName() == "cpus"
})
cpus := 0.0
for _, res := range cpuResources {
cpus += res.GetScalar().GetValue()
}
memResources := util.FilterResources(offer.Resources, func(res *mesos.Resource) bool {
return res.GetName() == "mem"
})
mems := 0.0
for _, res := range memResources {
mems += res.GetScalar().GetValue()
}
log.Infoln("Received Offer <", offer.Id.GetValue(), "> with cpus=", cpus, " mem=", mems)
remainingCpus := cpus
remainingMems := mems
var tasks []*mesos.TaskInfo
for sched.tasksLaunched < sched.totalTasks &&
CPUS_PER_TASK <= remainingCpus &&
MEM_PER_TASK <= remainingMems {
sched.tasksLaunched++
taskId := &mesos.TaskID{
Value: proto.String(strconv.Itoa(sched.tasksLaunched)),
}
task := &mesos.TaskInfo{
Name: proto.String("go-task-" + taskId.GetValue()),
TaskId: taskId,
SlaveId: offer.SlaveId,
Executor: sched.executor,
Resources: []*mesos.Resource{
util.NewScalarResource("cpus", CPUS_PER_TASK),
util.NewScalarResource("mem", MEM_PER_TASK),
},
}
log.Infof("Prepared task: %s with offer %s for launch\n", task.GetName(), offer.Id.GetValue())
tasks = append(tasks, task)
remainingCpus -= CPUS_PER_TASK
remainingMems -= MEM_PER_TASK
}
log.Infoln("Launching ", len(tasks), "tasks for offer", offer.Id.GetValue())
driver.LaunchTasks([]*mesos.OfferID{offer.Id}, tasks, &mesos.Filters{RefuseSeconds: proto.Float64(1)})
}
}
func (sched *ExampleScheduler) StatusUpdate(driver sched.SchedulerDriver, status *mesos.TaskStatus) {
log.Infoln("Status update: task", status.TaskId.GetValue(), " is in state ", status.State.Enum().String())
if status.GetState() == mesos.TaskState_TASK_FINISHED {
sched.tasksFinished++
}
if sched.tasksFinished >= sched.totalTasks {
log.Infoln("Total tasks completed, stopping framework.")
driver.Stop(false)
}
if status.GetState() == mesos.TaskState_TASK_LOST ||
status.GetState() == mesos.TaskState_TASK_KILLED ||
status.GetState() == mesos.TaskState_TASK_FAILED {
log.Infoln(
"Aborting because task", status.TaskId.GetValue(),
"is in unexpected state", status.State.String(),
"with message", status.GetMessage(),
)
driver.Abort()
}
}
func (sched *ExampleScheduler) OfferRescinded(sched.SchedulerDriver, *mesos.OfferID) {}
func (sched *ExampleScheduler) FrameworkMessage(sched.SchedulerDriver, *mesos.ExecutorID, *mesos.SlaveID, string) {
}
func (sched *ExampleScheduler) SlaveLost(sched.SchedulerDriver, *mesos.SlaveID) {}
func (sched *ExampleScheduler) ExecutorLost(sched.SchedulerDriver, *mesos.ExecutorID, *mesos.SlaveID, int) {
}
func (sched *ExampleScheduler) Error(driver sched.SchedulerDriver, err string) {
log.Infoln("Scheduler received error:", err)
}
// ----------------------- func init() ------------------------- //
func init() {
flag.Parse()
log.Infoln("Initializing the Example Scheduler...")
}
// returns (downloadURI, basename(path))
func serveExecutorArtifact(path string) (*string, string) {
serveFile := func(pattern string, filename string) {
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, filename)
})
}
// Create base path (http://foobar:5000/<base>)
pathSplit := strings.Split(path, "/")
var base string
if len(pathSplit) > 0 {
base = pathSplit[len(pathSplit)-1]
} else {
base = path
}
serveFile("/"+base, path)
hostURI := fmt.Sprintf("http://%s:%d/%s", *address, *artifactPort, base)
log.V(2).Infof("Hosting artifact '%s' at '%s'", path, hostURI)
return &hostURI, base
}
func prepareExecutorInfo() *mesos.ExecutorInfo {
executorUris := []*mesos.CommandInfo_URI{}
uri, executorCmd := serveExecutorArtifact(*executorPath)
executorUris = append(executorUris, &mesos.CommandInfo_URI{Value: uri, Executable: proto.Bool(true)})
executorCommand := fmt.Sprintf("./%s", executorCmd)
go http.ListenAndServe(fmt.Sprintf("%s:%d", *address, *artifactPort), nil)
log.V(2).Info("Serving executor artifacts...")
// Create mesos scheduler driver.
return &mesos.ExecutorInfo{
ExecutorId: util.NewExecutorID("default"),
Name: proto.String("Test Executor (Go)"),
Source: proto.String("go_test"),
Command: &mesos.CommandInfo{
Value: proto.String(executorCommand),
Uris: executorUris,
},
}
}
func parseIP(address string) net.IP {
addr, err := net.LookupIP(address)
if err != nil {
log.Fatal(err)
}
if len(addr) < 1 {
log.Fatalf("failed to parse IP from address '%v'", address)
}
return addr[0]
}
// ----------------------- func main() ------------------------- //
func main() {
// build command executor
exec := prepareExecutorInfo()
// the framework
fwinfo := &mesos.FrameworkInfo{
User: proto.String(""), // Mesos-go will fill in user.
Name: proto.String("Test Framework (Go)"),
}
cred := (*mesos.Credential)(nil)
if *mesosAuthPrincipal != "" {
fwinfo.Principal = proto.String(*mesosAuthPrincipal)
secret, err := ioutil.ReadFile(*mesosAuthSecretFile)
if err != nil {
log.Fatal(err)
}
cred = &mesos.Credential{
Principal: proto.String(*mesosAuthPrincipal),
Secret: secret,
}
}
bindingAddress := parseIP(*address)
config := sched.DriverConfig{
Scheduler: newExampleScheduler(exec),
Framework: fwinfo,
Master: *master,
Credential: cred,
BindingAddress: bindingAddress,
WithAuthContext: func(ctx context.Context) context.Context {
ctx = auth.WithLoginProvider(ctx, *authProvider)
ctx = sasl.WithBindingAddress(ctx, bindingAddress)
return ctx
},
}
driver, err := sched.NewMesosSchedulerDriver(config)
if err != nil {
log.Errorln("Unable to create a SchedulerDriver ", err.Error())
}
if stat, err := driver.Run(); err != nil {
log.Infof("Framework stopped with status %s and error: %s\n", stat.String(), err.Error())
}
}

View File

@ -1,40 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 healthchecker
import (
"time"
"github.com/mesos/mesos-go/upid"
)
// HealthChecker defines the interface of a health checker.
type HealthChecker interface {
// Start will start the health checker, and returns a notification channel.
// if the checker thinks the slave is unhealthy, it will send the timestamp
// via the channel.
Start() <-chan time.Time
// Pause will pause the slave health checker.
Pause()
// Continue will continue the slave health checker with a new slave upid.
Continue(slaveUPID *upid.UPID)
// Stop will stop the health checker. it should be called only once during
// the life span of the checker.
Stop()
}

View File

@ -1,61 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 healthchecker
import (
"time"
"github.com/mesos/mesos-go/upid"
"github.com/stretchr/testify/mock"
)
type MockedHealthChecker struct {
mock.Mock
ch chan time.Time
}
// NewMockedHealthChecker returns a new mocked health checker.
func NewMockedHealthChecker() *MockedHealthChecker {
return &MockedHealthChecker{ch: make(chan time.Time, 1)}
}
// Start will start the checker and returns the notification channel.
func (m *MockedHealthChecker) Start() <-chan time.Time {
m.Called()
return m.ch
}
// Pause will pause the slave health checker.
func (m *MockedHealthChecker) Pause() {
m.Called()
}
// Continue will continue the slave health checker with a new slave upid.
func (m *MockedHealthChecker) Continue(slaveUPID *upid.UPID) {
m.Called()
}
// Stop will stop the checker.
func (m *MockedHealthChecker) Stop() {
m.Called()
}
func (m *MockedHealthChecker) TriggerUnhealthyEvent() {
m.ch <- time.Now()
}

View File

@ -1,138 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 healthchecker
import (
"fmt"
"net/http"
"sync"
"time"
log "github.com/golang/glog"
"github.com/mesos/mesos-go/upid"
)
const (
defaultTimeout = time.Second
defaultCheckDuration = time.Second
defaultThreshold = 5
)
// SlaveHealthChecker is for checking the slave's health.
type SlaveHealthChecker struct {
sync.RWMutex
slaveUPID *upid.UPID
client *http.Client
threshold int
checkDuration time.Duration
continuousUnhealthyCount int
stop chan struct{}
ch chan time.Time
paused bool
}
// NewSlaveHealthChecker creates a slave health checker and return a notification channel.
// Each time the checker thinks the slave is unhealthy, it will send a notification through the channel.
func NewSlaveHealthChecker(slaveUPID *upid.UPID, threshold int, checkDuration time.Duration, timeout time.Duration) *SlaveHealthChecker {
checker := &SlaveHealthChecker{
slaveUPID: slaveUPID,
client: &http.Client{Timeout: timeout},
threshold: threshold,
checkDuration: checkDuration,
stop: make(chan struct{}),
ch: make(chan time.Time, 1),
}
if timeout == 0 {
checker.client.Timeout = defaultTimeout
}
if checkDuration == 0 {
checker.checkDuration = defaultCheckDuration
}
if threshold <= 0 {
checker.threshold = defaultThreshold
}
return checker
}
// Start will start the health checker and returns the notification channel.
func (s *SlaveHealthChecker) Start() <-chan time.Time {
go func() {
ticker := time.Tick(s.checkDuration)
for {
select {
case <-ticker:
s.RLock()
if !s.paused {
s.doCheck()
}
s.RUnlock()
case <-s.stop:
return
}
}
}()
return s.ch
}
// Pause will pause the slave health checker.
func (s *SlaveHealthChecker) Pause() {
s.Lock()
defer s.Unlock()
s.paused = true
}
// Continue will continue the slave health checker with a new slave upid.
func (s *SlaveHealthChecker) Continue(slaveUPID *upid.UPID) {
s.Lock()
defer s.Unlock()
s.paused = false
s.slaveUPID = slaveUPID
}
// Stop will stop the slave health checker.
// It should be called only once during the life span of the checker.
func (s *SlaveHealthChecker) Stop() {
close(s.stop)
}
func (s *SlaveHealthChecker) doCheck() {
path := fmt.Sprintf("http://%s:%s/%s/health", s.slaveUPID.Host, s.slaveUPID.Port, s.slaveUPID.ID)
resp, err := s.client.Head(path)
unhealthy := false
if err != nil {
log.Errorf("Failed to request the health path: %v\n", err)
unhealthy = true
} else if resp.StatusCode != http.StatusOK {
log.Errorf("Failed to request the health path: status: %v\n", resp.StatusCode)
unhealthy = true
}
if unhealthy {
s.continuousUnhealthyCount++
if s.continuousUnhealthyCount >= s.threshold {
select {
case s.ch <- time.Now(): // If no one is receiving the channel, then just skip it.
default:
}
s.continuousUnhealthyCount = 0
}
return
}
s.continuousUnhealthyCount = 0
resp.Body.Close()
}

View File

@ -1,262 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 healthchecker
import (
"fmt"
"net/http"
"net/http/httptest"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/mesos/mesos-go/upid"
"github.com/stretchr/testify/assert"
)
type thresholdMonitor struct {
cnt int32
threshold int32
}
func newThresholdMonitor(threshold int) *thresholdMonitor {
return &thresholdMonitor{threshold: int32(threshold)}
}
// incAndTest returns true if the threshold is reached.
func (t *thresholdMonitor) incAndTest() bool {
if atomic.AddInt32(&t.cnt, 1) >= t.threshold {
return false
}
return true
}
// blockedServer replies only threshold times, after that
// it will block.
type blockedServer struct {
th *thresholdMonitor
ch chan struct{}
}
func newBlockedServer(threshold int) *blockedServer {
return &blockedServer{
th: newThresholdMonitor(threshold),
ch: make(chan struct{}),
}
}
func (s *blockedServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if s.th.incAndTest() {
return
}
<-s.ch
}
func (s *blockedServer) stop() {
close(s.ch)
}
// eofServer will close the connection after it replies for threshold times.
// Thus the health checker will get an EOF error.
type eofServer struct {
th *thresholdMonitor
}
func newEOFServer(threshold int) *eofServer {
return &eofServer{newThresholdMonitor(threshold)}
}
func (s *eofServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if s.th.incAndTest() {
return
}
hj := w.(http.Hijacker)
conn, _, err := hj.Hijack()
if err != nil {
panic("Cannot hijack")
}
conn.Close()
}
// errorStatusCodeServer will reply error status code (e.g. 503) after the
// it replies for threhold time.
type errorStatusCodeServer struct {
th *thresholdMonitor
}
func newErrorStatusServer(threshold int) *errorStatusCodeServer {
return &errorStatusCodeServer{newThresholdMonitor(threshold)}
}
func (s *errorStatusCodeServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if s.th.incAndTest() {
return
}
w.WriteHeader(http.StatusServiceUnavailable)
}
// goodServer always returns status ok.
type goodServer bool
func (s *goodServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
// partitionedServer returns status ok at some first requests.
// Then it will block for a while, and then reply again.
type partitionedServer struct {
healthyCnt int32
partitionCnt int32
cnt int32
mutex *sync.Mutex
cond *sync.Cond
}
func newPartitionedServer(healthyCnt, partitionCnt int) *partitionedServer {
mutex := new(sync.Mutex)
cond := sync.NewCond(mutex)
return &partitionedServer{
healthyCnt: int32(healthyCnt),
partitionCnt: int32(partitionCnt),
mutex: mutex,
cond: cond,
}
}
func (s *partitionedServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
cnt := atomic.AddInt32(&s.cnt, 1)
if cnt < s.healthyCnt {
return
}
if cnt < s.healthyCnt+s.partitionCnt {
s.mutex.Lock()
defer s.mutex.Unlock()
s.cond.Wait()
return
}
s.mutex.Lock()
defer s.mutex.Unlock()
s.cond.Broadcast()
}
func TestSlaveHealthCheckerFailedOnBlockedSlave(t *testing.T) {
s := newBlockedServer(5)
ts := httptest.NewUnstartedServer(s)
ts.Start()
defer ts.Close()
upid, err := upid.Parse(fmt.Sprintf("slave@%s", ts.Listener.Addr().String()))
assert.NoError(t, err)
checker := NewSlaveHealthChecker(upid, 10, time.Millisecond*10, time.Millisecond*10)
ch := checker.Start()
defer checker.Stop()
select {
case <-time.After(time.Second):
s.stop()
t.Fatal("timeout")
case <-ch:
s.stop()
assert.True(t, atomic.LoadInt32(&s.th.cnt) > 10)
}
}
func TestSlaveHealthCheckerFailedOnEOFSlave(t *testing.T) {
s := newEOFServer(5)
ts := httptest.NewUnstartedServer(s)
ts.Start()
defer ts.Close()
upid, err := upid.Parse(fmt.Sprintf("slave@%s", ts.Listener.Addr().String()))
assert.NoError(t, err)
checker := NewSlaveHealthChecker(upid, 10, time.Millisecond*10, time.Millisecond*10)
ch := checker.Start()
defer checker.Stop()
select {
case <-time.After(time.Second):
t.Fatal("timeout")
case <-ch:
assert.True(t, atomic.LoadInt32(&s.th.cnt) > 10)
}
}
func TestSlaveHealthCheckerFailedOnErrorStatusSlave(t *testing.T) {
s := newErrorStatusServer(5)
ts := httptest.NewUnstartedServer(s)
ts.Start()
defer ts.Close()
upid, err := upid.Parse(fmt.Sprintf("slave@%s", ts.Listener.Addr().String()))
assert.NoError(t, err)
checker := NewSlaveHealthChecker(upid, 10, time.Millisecond*10, time.Millisecond*10)
ch := checker.Start()
defer checker.Stop()
select {
case <-time.After(time.Second):
t.Fatal("timeout")
case <-ch:
assert.True(t, atomic.LoadInt32(&s.th.cnt) > 10)
}
}
func TestSlaveHealthCheckerSucceed(t *testing.T) {
s := new(goodServer)
ts := httptest.NewUnstartedServer(s)
ts.Start()
defer ts.Close()
upid, err := upid.Parse(fmt.Sprintf("slave@%s", ts.Listener.Addr().String()))
assert.NoError(t, err)
checker := NewSlaveHealthChecker(upid, 10, time.Millisecond*10, time.Millisecond*10)
ch := checker.Start()
defer checker.Stop()
select {
case <-time.After(time.Second):
assert.Equal(t, 0, checker.continuousUnhealthyCount)
case <-ch:
t.Fatal("Shouldn't get unhealthy notification")
}
}
func TestSlaveHealthCheckerPartitonedSlave(t *testing.T) {
s := newPartitionedServer(5, 9)
ts := httptest.NewUnstartedServer(s)
ts.Start()
defer ts.Close()
upid, err := upid.Parse(fmt.Sprintf("slave@%s", ts.Listener.Addr().String()))
assert.NoError(t, err)
checker := NewSlaveHealthChecker(upid, 10, time.Millisecond*10, time.Millisecond*10)
ch := checker.Start()
defer checker.Stop()
select {
case <-time.After(time.Second):
assert.Equal(t, 0, checker.continuousUnhealthyCount)
case <-ch:
t.Fatal("Shouldn't get unhealthy notification")
}
}

View File

@ -1,3 +0,0 @@
// This package was previously the home of the native bindings. Please use the
// native branch if you need to build against the native bindings.
package mesos

View File

@ -1,135 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
//Collection of resources for teting mesos artifacts.
package testutil
import (
"bytes"
"fmt"
"github.com/gogo/protobuf/proto"
log "github.com/golang/glog"
"github.com/mesos/mesos-go/upid"
"github.com/stretchr/testify/assert"
"io"
"net"
"net/http"
"net/http/httptest"
"os"
"reflect"
"testing"
)
//MockMesosHttpProcess represents a remote http process: master or slave.
type MockMesosHttpServer struct {
PID *upid.UPID
Addr string
server *httptest.Server
t *testing.T
when map[string]http.HandlerFunc
}
type When interface {
Do(http.HandlerFunc)
}
type WhenFunc func(http.HandlerFunc)
func (w WhenFunc) Do(f http.HandlerFunc) {
w(f)
}
func (m *MockMesosHttpServer) On(uri string) When {
log.V(2).Infof("when %v do something special", uri)
return WhenFunc(func(f http.HandlerFunc) {
log.V(2).Infof("registered callback for %v", uri)
m.when[uri] = f
})
}
func NewMockMasterHttpServer(t *testing.T, handler func(rsp http.ResponseWriter, req *http.Request)) *MockMesosHttpServer {
var server *httptest.Server
when := make(map[string]http.HandlerFunc)
stateHandler := func(rsp http.ResponseWriter, req *http.Request) {
if "/state.json" == req.RequestURI {
state := fmt.Sprintf(`{ "leader": "master@%v" }`, server.Listener.Addr())
log.V(1).Infof("returning JSON %v", state)
io.WriteString(rsp, state)
} else if f, found := when[req.RequestURI]; found {
f(rsp, req)
} else {
handler(rsp, req)
}
}
server = httptest.NewServer(http.HandlerFunc(stateHandler))
assert.NotNil(t, server)
addr := server.Listener.Addr().String()
pid, err := upid.Parse("master@" + addr)
assert.NoError(t, err)
assert.NotNil(t, pid)
log.Infoln("Created test Master http server with PID", pid.String())
return &MockMesosHttpServer{PID: pid, Addr: addr, server: server, t: t, when: when}
}
func NewMockSlaveHttpServer(t *testing.T, handler func(rsp http.ResponseWriter, req *http.Request)) *MockMesosHttpServer {
server := httptest.NewServer(http.HandlerFunc(handler))
assert.NotNil(t, server)
addr := server.Listener.Addr().String()
pid, err := upid.Parse("slave(1)@" + addr)
assert.NoError(t, err)
assert.NotNil(t, pid)
assert.NoError(t, os.Setenv("MESOS_SLAVE_PID", pid.String()))
assert.NoError(t, os.Setenv("MESOS_SLAVE_ID", "test-slave-001"))
log.Infoln("Created test Slave http server with PID", pid.String())
return &MockMesosHttpServer{PID: pid, Addr: addr, server: server, t: t}
}
func (s *MockMesosHttpServer) Close() {
s.server.Close()
}
//MockMesosClient Http client to communicate with mesos processes (master,sched,exec)
type MockMesosClient struct {
pid *upid.UPID
t *testing.T
}
func NewMockMesosClient(t *testing.T, pid *upid.UPID) *MockMesosClient {
return &MockMesosClient{t: t, pid: pid}
}
// sendMessage Mocks sending event messages to a processes such as master, sched or exec.
func (c *MockMesosClient) SendMessage(targetPid *upid.UPID, message proto.Message) {
if c.t == nil {
panic("MockMesosClient needs a testing context.")
}
messageName := reflect.TypeOf(message).Elem().Name()
data, err := proto.Marshal(message)
assert.NoError(c.t, err)
hostport := net.JoinHostPort(targetPid.Host, targetPid.Port)
targetURL := fmt.Sprintf("http://%s/%s/mesos.internal.%s", hostport, targetPid.ID, messageName)
log.Infoln("MockMesosClient Sending message to", targetURL)
req, err := http.NewRequest("POST", targetURL, bytes.NewReader(data))
assert.NoError(c.t, err)
req.Header.Add("Libprocess-From", c.pid.String())
req.Header.Add("Content-Type", "application/x-protobuf")
resp, err := http.DefaultClient.Do(req)
assert.NoError(c.t, err)
assert.Equal(c.t, http.StatusAccepted, resp.StatusCode)
}

View File

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