1package awstesting
2
3import (
4	"io"
5	"os"
6	"strings"
7	"time"
8
9	"github.com/aws/aws-sdk-go/private/util"
10)
11
12// ZeroReader is a io.Reader which will always write zeros to the byte slice provided.
13type ZeroReader struct{}
14
15// Read fills the provided byte slice with zeros returning the number of bytes written.
16func (r *ZeroReader) Read(b []byte) (int, error) {
17	for i := 0; i < len(b); i++ {
18		b[i] = 0
19	}
20	return len(b), nil
21}
22
23// ReadCloser is a io.ReadCloser for unit testing.
24// Designed to test for leaks and whether a handle has
25// been closed
26type ReadCloser struct {
27	Size     int
28	Closed   bool
29	set      bool
30	FillData func(bool, []byte, int, int)
31}
32
33// Read will call FillData and fill it with whatever data needed.
34// Decrements the size until zero, then return io.EOF.
35func (r *ReadCloser) Read(b []byte) (int, error) {
36	if r.Closed {
37		return 0, io.EOF
38	}
39
40	delta := len(b)
41	if delta > r.Size {
42		delta = r.Size
43	}
44	r.Size -= delta
45
46	for i := 0; i < delta; i++ {
47		b[i] = 'a'
48	}
49
50	if r.FillData != nil {
51		r.FillData(r.set, b, r.Size, delta)
52	}
53	r.set = true
54
55	if r.Size > 0 {
56		return delta, nil
57	}
58	return delta, io.EOF
59}
60
61// Close sets Closed to true and returns no error
62func (r *ReadCloser) Close() error {
63	r.Closed = true
64	return nil
65}
66
67// SortedKeys returns a sorted slice of keys of a map.
68func SortedKeys(m map[string]interface{}) []string {
69	return util.SortedKeys(m)
70}
71
72// A FakeContext provides a simple stub implementation of a Context
73type FakeContext struct {
74	Error  error
75	DoneCh chan struct{}
76}
77
78// Deadline always will return not set
79func (c *FakeContext) Deadline() (deadline time.Time, ok bool) {
80	return time.Time{}, false
81}
82
83// Done returns a read channel for listening to the Done event
84func (c *FakeContext) Done() <-chan struct{} {
85	return c.DoneCh
86}
87
88// Err returns the error, is nil if not set.
89func (c *FakeContext) Err() error {
90	return c.Error
91}
92
93// Value ignores the Value and always returns nil
94func (c *FakeContext) Value(key interface{}) interface{} {
95	return nil
96}
97
98// StashEnv stashes the current environment variables and returns an array of
99// all environment values as key=val strings.
100//
101// Deprecated: StashEnv exists for backward compatibility and may be removed from the future iterations.
102// It is not `internal` so that if you really need to use its functionality, and understand breaking
103// changes will be made, you are able to.
104func StashEnv() []string {
105	env := os.Environ()
106	os.Clearenv()
107	return env
108}
109
110// PopEnv takes the list of the environment values and injects them into the
111// process's environment variable data. Clears any existing environment values
112// that may already exist.
113//
114// Deprecated: PopEnv exists for backward compatibility and may be removed from the future iterations.
115// It is not `internal` so that if you really need to use its functionality, and understand breaking
116// changes will be made, you are able to.
117func PopEnv(env []string) {
118	os.Clearenv()
119
120	for _, e := range env {
121		p := strings.SplitN(e, "=", 2)
122		k, v := p[0], ""
123		if len(p) > 1 {
124			v = p[1]
125		}
126		os.Setenv(k, v)
127	}
128}
129