mirror of
https://github.com/Oxalide/vsphere-influxdb-go.git
synced 2023-10-10 11:36:51 +00:00
add vendoring with go dep
This commit is contained in:
73
vendor/github.com/vmware/govmomi/vim25/progress/aggregator.go
generated
vendored
Normal file
73
vendor/github.com/vmware/govmomi/vim25/progress/aggregator.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
import "sync"
|
||||
|
||||
type Aggregator struct {
|
||||
downstream Sinker
|
||||
upstream chan (<-chan Report)
|
||||
|
||||
done chan struct{}
|
||||
w sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewAggregator(s Sinker) *Aggregator {
|
||||
a := &Aggregator{
|
||||
downstream: s,
|
||||
upstream: make(chan (<-chan Report)),
|
||||
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
||||
a.w.Add(1)
|
||||
go a.loop()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Aggregator) loop() {
|
||||
defer a.w.Done()
|
||||
|
||||
dch := a.downstream.Sink()
|
||||
defer close(dch)
|
||||
|
||||
for {
|
||||
select {
|
||||
case uch := <-a.upstream:
|
||||
// Drain upstream channel
|
||||
for e := range uch {
|
||||
dch <- e
|
||||
}
|
||||
case <-a.done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Aggregator) Sink() chan<- Report {
|
||||
ch := make(chan Report)
|
||||
a.upstream <- ch
|
||||
return ch
|
||||
}
|
||||
|
||||
// Done marks the aggregator as done. No more calls to Sink() may be made and
|
||||
// the downstream progress report channel will be closed when Done() returns.
|
||||
func (a *Aggregator) Done() {
|
||||
close(a.done)
|
||||
a.w.Wait()
|
||||
}
|
81
vendor/github.com/vmware/govmomi/vim25/progress/aggregator_test.go
generated
vendored
Normal file
81
vendor/github.com/vmware/govmomi/vim25/progress/aggregator_test.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestAggregatorNoSinks(t *testing.T) {
|
||||
ch := make(chan Report)
|
||||
a := NewAggregator(dummySinker{ch})
|
||||
a.Done()
|
||||
|
||||
_, ok := <-ch
|
||||
if ok {
|
||||
t.Errorf("Expected channel to be closed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAggregatorMultipleSinks(t *testing.T) {
|
||||
ch := make(chan Report)
|
||||
a := NewAggregator(dummySinker{ch})
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
go func(ch chan<- Report) {
|
||||
ch <- dummyReport{}
|
||||
ch <- dummyReport{}
|
||||
close(ch)
|
||||
}(a.Sink())
|
||||
|
||||
<-ch
|
||||
<-ch
|
||||
}
|
||||
|
||||
a.Done()
|
||||
|
||||
_, ok := <-ch
|
||||
if ok {
|
||||
t.Errorf("Expected channel to be closed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAggregatorSinkInFlightOnDone(t *testing.T) {
|
||||
ch := make(chan Report)
|
||||
a := NewAggregator(dummySinker{ch})
|
||||
|
||||
// Simulate upstream
|
||||
go func(ch chan<- Report) {
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
ch <- dummyReport{}
|
||||
close(ch)
|
||||
}(a.Sink())
|
||||
|
||||
// Drain downstream
|
||||
go func(ch <-chan Report) {
|
||||
<-ch
|
||||
}(ch)
|
||||
|
||||
// This should wait for upstream to complete
|
||||
a.Done()
|
||||
|
||||
_, ok := <-ch
|
||||
if ok {
|
||||
t.Errorf("Expected channel to be closed")
|
||||
}
|
||||
}
|
43
vendor/github.com/vmware/govmomi/vim25/progress/common_test.go
generated
vendored
Normal file
43
vendor/github.com/vmware/govmomi/vim25/progress/common_test.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
type dummySinker struct {
|
||||
ch chan Report
|
||||
}
|
||||
|
||||
func (d dummySinker) Sink() chan<- Report {
|
||||
return d.ch
|
||||
}
|
||||
|
||||
type dummyReport struct {
|
||||
p float32
|
||||
d string
|
||||
e error
|
||||
}
|
||||
|
||||
func (p dummyReport) Percentage() float32 {
|
||||
return p.p
|
||||
}
|
||||
|
||||
func (p dummyReport) Detail() string {
|
||||
return p.d
|
||||
}
|
||||
|
||||
func (p dummyReport) Error() error {
|
||||
return p.e
|
||||
}
|
32
vendor/github.com/vmware/govmomi/vim25/progress/doc.go
generated
vendored
Normal file
32
vendor/github.com/vmware/govmomi/vim25/progress/doc.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
/*
|
||||
The progress package contains functionality to deal with progress reporting.
|
||||
The functionality is built to serve progress reporting for infrastructure
|
||||
operations when talking the vSphere API, but is generic enough to be used
|
||||
elsewhere.
|
||||
|
||||
At the core of this progress reporting API lies the Sinker interface. This
|
||||
interface is implemented by any object that can act as a sink for progress
|
||||
reports. Callers of the Sink() function receives a send-only channel for
|
||||
progress reports. They are responsible for closing the channel when done.
|
||||
This semantic makes it easy to keep track of multiple progress report channels;
|
||||
they are only created when Sink() is called and assumed closed when any
|
||||
function that receives a Sinker parameter returns.
|
||||
*/
|
54
vendor/github.com/vmware/govmomi/vim25/progress/prefix.go
generated
vendored
Normal file
54
vendor/github.com/vmware/govmomi/vim25/progress/prefix.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
import "fmt"
|
||||
|
||||
type prefixedReport struct {
|
||||
Report
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (r prefixedReport) Detail() string {
|
||||
if d := r.Report.Detail(); d != "" {
|
||||
return fmt.Sprintf("%s: %s", r.prefix, d)
|
||||
}
|
||||
|
||||
return r.prefix
|
||||
}
|
||||
|
||||
func prefixLoop(upstream <-chan Report, downstream chan<- Report, prefix string) {
|
||||
defer close(downstream)
|
||||
|
||||
for r := range upstream {
|
||||
downstream <- prefixedReport{
|
||||
Report: r,
|
||||
prefix: prefix,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Prefix(s Sinker, prefix string) Sinker {
|
||||
fn := func() chan<- Report {
|
||||
upstream := make(chan Report)
|
||||
downstream := s.Sink()
|
||||
go prefixLoop(upstream, downstream, prefix)
|
||||
return upstream
|
||||
}
|
||||
|
||||
return SinkFunc(fn)
|
||||
}
|
40
vendor/github.com/vmware/govmomi/vim25/progress/prefix_test.go
generated
vendored
Normal file
40
vendor/github.com/vmware/govmomi/vim25/progress/prefix_test.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPrefix(t *testing.T) {
|
||||
var r Report
|
||||
|
||||
ch := make(chan Report, 1)
|
||||
s := Prefix(dummySinker{ch}, "prefix").Sink()
|
||||
|
||||
// No detail
|
||||
s <- dummyReport{d: ""}
|
||||
r = <-ch
|
||||
if r.Detail() != "prefix" {
|
||||
t.Errorf("Expected detail to be prefixed")
|
||||
}
|
||||
|
||||
// With detail
|
||||
s <- dummyReport{d: "something"}
|
||||
r = <-ch
|
||||
if r.Detail() != "prefix: something" {
|
||||
t.Errorf("Expected detail to be prefixed")
|
||||
}
|
||||
}
|
177
vendor/github.com/vmware/govmomi/vim25/progress/reader.go
generated
vendored
Normal file
177
vendor/github.com/vmware/govmomi/vim25/progress/reader.go
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 VMware, 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 progress
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type readerReport struct {
|
||||
t time.Time
|
||||
|
||||
pos int64
|
||||
size int64
|
||||
bps *uint64
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
func (r readerReport) Percentage() float32 {
|
||||
return 100.0 * float32(r.pos) / float32(r.size)
|
||||
}
|
||||
|
||||
func (r readerReport) Detail() string {
|
||||
const (
|
||||
KiB = 1024
|
||||
MiB = 1024 * KiB
|
||||
GiB = 1024 * MiB
|
||||
)
|
||||
|
||||
// Use the reader's bps field, so this report returns an up-to-date number.
|
||||
//
|
||||
// For example: if there hasn't been progress for the last 5 seconds, the
|
||||
// most recent report should return "0B/s".
|
||||
//
|
||||
bps := atomic.LoadUint64(r.bps)
|
||||
|
||||
switch {
|
||||
case bps >= GiB:
|
||||
return fmt.Sprintf("%.1fGiB/s", float32(bps)/float32(GiB))
|
||||
case bps >= MiB:
|
||||
return fmt.Sprintf("%.1fMiB/s", float32(bps)/float32(MiB))
|
||||
case bps >= KiB:
|
||||
return fmt.Sprintf("%.1fKiB/s", float32(bps)/float32(KiB))
|
||||
default:
|
||||
return fmt.Sprintf("%dB/s", bps)
|
||||
}
|
||||
}
|
||||
|
||||
func (p readerReport) Error() error {
|
||||
return p.err
|
||||
}
|
||||
|
||||
// reader wraps an io.Reader and sends a progress report over a channel for
|
||||
// every read it handles.
|
||||
type reader struct {
|
||||
r io.Reader
|
||||
|
||||
pos int64
|
||||
size int64
|
||||
|
||||
bps uint64
|
||||
|
||||
ch chan<- Report
|
||||
}
|
||||
|
||||
func NewReader(s Sinker, r io.Reader, size int64) *reader {
|
||||
pr := reader{
|
||||
r: r,
|
||||
|
||||
size: size,
|
||||
}
|
||||
|
||||
// Reports must be sent downstream and to the bps computation loop.
|
||||
pr.ch = Tee(s, newBpsLoop(&pr.bps)).Sink()
|
||||
|
||||
return &pr
|
||||
}
|
||||
|
||||
// Read calls the Read function on the underlying io.Reader. Additionally,
|
||||
// every read causes a progress report to be sent to the progress reader's
|
||||
// underlying channel.
|
||||
func (r *reader) Read(b []byte) (int, error) {
|
||||
n, err := r.r.Read(b)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
r.pos += int64(n)
|
||||
q := readerReport{
|
||||
t: time.Now(),
|
||||
pos: r.pos,
|
||||
size: r.size,
|
||||
bps: &r.bps,
|
||||
}
|
||||
|
||||
r.ch <- q
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Done marks the progress reader as done, optionally including an error in the
|
||||
// progress report. After sending it, the underlying channel is closed.
|
||||
func (r *reader) Done(err error) {
|
||||
q := readerReport{
|
||||
t: time.Now(),
|
||||
pos: r.pos,
|
||||
size: r.size,
|
||||
bps: &r.bps,
|
||||
err: err,
|
||||
}
|
||||
|
||||
r.ch <- q
|
||||
close(r.ch)
|
||||
}
|
||||
|
||||
// newBpsLoop returns a sink that monitors and stores throughput.
|
||||
func newBpsLoop(dst *uint64) SinkFunc {
|
||||
fn := func() chan<- Report {
|
||||
sink := make(chan Report)
|
||||
go bpsLoop(sink, dst)
|
||||
return sink
|
||||
}
|
||||
|
||||
return fn
|
||||
}
|
||||
|
||||
func bpsLoop(ch <-chan Report, dst *uint64) {
|
||||
l := list.New()
|
||||
|
||||
for {
|
||||
var tch <-chan time.Time
|
||||
|
||||
// Setup timer for front of list to become stale.
|
||||
if e := l.Front(); e != nil {
|
||||
dt := time.Second - time.Now().Sub(e.Value.(readerReport).t)
|
||||
tch = time.After(dt)
|
||||
}
|
||||
|
||||
select {
|
||||
case q, ok := <-ch:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
l.PushBack(q)
|
||||
case <-tch:
|
||||
l.Remove(l.Front())
|
||||
}
|
||||
|
||||
// Compute new bps
|
||||
if l.Len() == 0 {
|
||||
atomic.StoreUint64(dst, 0)
|
||||
} else {
|
||||
f := l.Front().Value.(readerReport)
|
||||
b := l.Back().Value.(readerReport)
|
||||
atomic.StoreUint64(dst, uint64(b.pos-f.pos))
|
||||
}
|
||||
}
|
||||
}
|
90
vendor/github.com/vmware/govmomi/vim25/progress/reader_test.go
generated
vendored
Normal file
90
vendor/github.com/vmware/govmomi/vim25/progress/reader_test.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReader(t *testing.T) {
|
||||
s := "helloworld"
|
||||
ch := make(chan Report, 1)
|
||||
pr := NewReader(&dummySinker{ch}, strings.NewReader(s), int64(len(s)))
|
||||
|
||||
var buf [10]byte
|
||||
var q Report
|
||||
var n int
|
||||
var err error
|
||||
|
||||
// Read first byte
|
||||
n, err = pr.Read(buf[0:1])
|
||||
if n != 1 {
|
||||
t.Errorf("Expected n=1, but got: %d", n)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error: %s", err)
|
||||
}
|
||||
|
||||
q = <-ch
|
||||
if q.Error() != nil {
|
||||
t.Errorf("Error: %s", err)
|
||||
}
|
||||
|
||||
if f := q.Percentage(); f != 10.0 {
|
||||
t.Errorf("Expected percentage after 1 byte to be 10%%, but got: %.0f%%", f)
|
||||
}
|
||||
|
||||
// Read remaining bytes
|
||||
n, err = pr.Read(buf[:])
|
||||
if n != 9 {
|
||||
t.Errorf("Expected n=1, but got: %d", n)
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("Error: %s", err)
|
||||
}
|
||||
|
||||
q = <-ch
|
||||
if q.Error() != nil {
|
||||
t.Errorf("Error: %s", err)
|
||||
}
|
||||
|
||||
if f := q.Percentage(); f != 100.0 {
|
||||
t.Errorf("Expected percentage after 10 bytes to be 100%%, but got: %.0f%%", f)
|
||||
}
|
||||
|
||||
// Read EOF
|
||||
_, err = pr.Read(buf[:])
|
||||
if err != io.EOF {
|
||||
t.Errorf("Expected io.EOF, but got: %s", err)
|
||||
}
|
||||
|
||||
// Mark progress reader as done
|
||||
pr.Done(io.EOF)
|
||||
q = <-ch
|
||||
if err != io.EOF {
|
||||
t.Errorf("Expected io.EOF, but got: %s", err)
|
||||
}
|
||||
|
||||
// Progress channel should be closed after progress reader is marked done
|
||||
_, ok := <-ch
|
||||
if ok {
|
||||
t.Errorf("Expected channel to be closed")
|
||||
}
|
||||
}
|
26
vendor/github.com/vmware/govmomi/vim25/progress/report.go
generated
vendored
Normal file
26
vendor/github.com/vmware/govmomi/vim25/progress/report.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
// Report defines the interface for types that can deliver progress reports.
|
||||
// Examples include uploads/downloads in the http client and the task info
|
||||
// field in the task managed object.
|
||||
type Report interface {
|
||||
Percentage() float32
|
||||
Detail() string
|
||||
Error() error
|
||||
}
|
76
vendor/github.com/vmware/govmomi/vim25/progress/scale.go
generated
vendored
Normal file
76
vendor/github.com/vmware/govmomi/vim25/progress/scale.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
type scaledReport struct {
|
||||
Report
|
||||
n int
|
||||
i int
|
||||
}
|
||||
|
||||
func (r scaledReport) Percentage() float32 {
|
||||
b := 100 * float32(r.i) / float32(r.n)
|
||||
return b + (r.Report.Percentage() / float32(r.n))
|
||||
}
|
||||
|
||||
type scaleOne struct {
|
||||
s Sinker
|
||||
n int
|
||||
i int
|
||||
}
|
||||
|
||||
func (s scaleOne) Sink() chan<- Report {
|
||||
upstream := make(chan Report)
|
||||
downstream := s.s.Sink()
|
||||
go s.loop(upstream, downstream)
|
||||
return upstream
|
||||
}
|
||||
|
||||
func (s scaleOne) loop(upstream <-chan Report, downstream chan<- Report) {
|
||||
defer close(downstream)
|
||||
|
||||
for r := range upstream {
|
||||
downstream <- scaledReport{
|
||||
Report: r,
|
||||
n: s.n,
|
||||
i: s.i,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type scaleMany struct {
|
||||
s Sinker
|
||||
n int
|
||||
i int
|
||||
}
|
||||
|
||||
func Scale(s Sinker, n int) Sinker {
|
||||
return &scaleMany{
|
||||
s: s,
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scaleMany) Sink() chan<- Report {
|
||||
if s.i == s.n {
|
||||
s.n++
|
||||
}
|
||||
|
||||
ch := scaleOne{s: s.s, n: s.n, i: s.i}.Sink()
|
||||
s.i++
|
||||
return ch
|
||||
}
|
45
vendor/github.com/vmware/govmomi/vim25/progress/scale_test.go
generated
vendored
Normal file
45
vendor/github.com/vmware/govmomi/vim25/progress/scale_test.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestScaleMany(t *testing.T) {
|
||||
ch := make(chan Report)
|
||||
a := NewAggregator(dummySinker{ch})
|
||||
defer a.Done()
|
||||
|
||||
s := Scale(a, 5)
|
||||
|
||||
go func() {
|
||||
for i := 0; i < 5; i++ {
|
||||
go func(ch chan<- Report) {
|
||||
ch <- dummyReport{p: 0.0}
|
||||
ch <- dummyReport{p: 50.0}
|
||||
close(ch)
|
||||
}(s.Sink())
|
||||
}
|
||||
}()
|
||||
|
||||
// Expect percentages to be scaled across sinks
|
||||
for p := float32(0.0); p < 100.0; p += 10.0 {
|
||||
r := <-ch
|
||||
if r.Percentage() != p {
|
||||
t.Errorf("Expected percentage to be: %.0f%%", p)
|
||||
}
|
||||
}
|
||||
}
|
33
vendor/github.com/vmware/govmomi/vim25/progress/sinker.go
generated
vendored
Normal file
33
vendor/github.com/vmware/govmomi/vim25/progress/sinker.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
// Sinker defines what is expected of a type that can act as a sink for
|
||||
// progress reports. The semantics are as follows. If you call Sink(), you are
|
||||
// responsible for closing the returned channel. Closing this channel means
|
||||
// that the related task is done, or resulted in error.
|
||||
type Sinker interface {
|
||||
Sink() chan<- Report
|
||||
}
|
||||
|
||||
// SinkFunc defines a function that returns a progress report channel.
|
||||
type SinkFunc func() chan<- Report
|
||||
|
||||
// Sink makes the SinkFunc implement the Sinker interface.
|
||||
func (fn SinkFunc) Sink() chan<- Report {
|
||||
return fn()
|
||||
}
|
41
vendor/github.com/vmware/govmomi/vim25/progress/tee.go
generated
vendored
Normal file
41
vendor/github.com/vmware/govmomi/vim25/progress/tee.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
// Tee works like Unix tee; it forwards all progress reports it receives to the
|
||||
// specified sinks
|
||||
func Tee(s1, s2 Sinker) Sinker {
|
||||
fn := func() chan<- Report {
|
||||
d1 := s1.Sink()
|
||||
d2 := s2.Sink()
|
||||
u := make(chan Report)
|
||||
go tee(u, d1, d2)
|
||||
return u
|
||||
}
|
||||
|
||||
return SinkFunc(fn)
|
||||
}
|
||||
|
||||
func tee(u <-chan Report, d1, d2 chan<- Report) {
|
||||
defer close(d1)
|
||||
defer close(d2)
|
||||
|
||||
for r := range u {
|
||||
d1 <- r
|
||||
d2 <- r
|
||||
}
|
||||
}
|
46
vendor/github.com/vmware/govmomi/vim25/progress/tee_test.go
generated
vendored
Normal file
46
vendor/github.com/vmware/govmomi/vim25/progress/tee_test.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright (c) 2014 VMware, 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 progress
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestTee(t *testing.T) {
|
||||
var ok bool
|
||||
|
||||
ch1 := make(chan Report)
|
||||
ch2 := make(chan Report)
|
||||
|
||||
s := Tee(&dummySinker{ch: ch1}, &dummySinker{ch: ch2})
|
||||
|
||||
in := s.Sink()
|
||||
in <- dummyReport{}
|
||||
close(in)
|
||||
|
||||
// Receive dummy on both sinks
|
||||
<-ch1
|
||||
<-ch2
|
||||
|
||||
_, ok = <-ch1
|
||||
if ok {
|
||||
t.Errorf("Expected channel to be closed")
|
||||
}
|
||||
|
||||
_, ok = <-ch2
|
||||
if ok {
|
||||
t.Errorf("Expected channel to be closed")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user