ssh_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package tunneler
  14. import (
  15. "context"
  16. "fmt"
  17. "net"
  18. "os"
  19. "path/filepath"
  20. "testing"
  21. "time"
  22. "github.com/stretchr/testify/assert"
  23. "k8s.io/apimachinery/pkg/util/clock"
  24. )
  25. // TestSecondsSinceSync verifies that proper results are returned
  26. // when checking the time between syncs
  27. func TestSecondsSinceSync(t *testing.T) {
  28. tests := []struct {
  29. name string
  30. lastSync int64
  31. clock *clock.FakeClock
  32. want int64
  33. }{
  34. {
  35. name: "Nano Second. No difference",
  36. lastSync: time.Date(2015, time.January, 1, 1, 1, 1, 1, time.UTC).Unix(),
  37. clock: clock.NewFakeClock(time.Date(2015, time.January, 1, 1, 1, 1, 2, time.UTC)),
  38. want: int64(0),
  39. },
  40. {
  41. name: "Second",
  42. lastSync: time.Date(2015, time.January, 1, 1, 1, 1, 1, time.UTC).Unix(),
  43. clock: clock.NewFakeClock(time.Date(2015, time.January, 1, 1, 1, 2, 1, time.UTC)),
  44. want: int64(1),
  45. },
  46. {
  47. name: "Minute",
  48. lastSync: time.Date(2015, time.January, 1, 1, 1, 1, 1, time.UTC).Unix(),
  49. clock: clock.NewFakeClock(time.Date(2015, time.January, 1, 1, 2, 1, 1, time.UTC)),
  50. want: int64(60),
  51. },
  52. {
  53. name: "Hour",
  54. lastSync: time.Date(2015, time.January, 1, 1, 1, 1, 1, time.UTC).Unix(),
  55. clock: clock.NewFakeClock(time.Date(2015, time.January, 1, 2, 1, 1, 1, time.UTC)),
  56. want: int64(3600),
  57. },
  58. {
  59. name: "Day",
  60. lastSync: time.Date(2015, time.January, 1, 1, 1, 1, 1, time.UTC).Unix(),
  61. clock: clock.NewFakeClock(time.Date(2015, time.January, 2, 1, 1, 1, 1, time.UTC)),
  62. want: int64(86400),
  63. },
  64. {
  65. name: "Month",
  66. lastSync: time.Date(2015, time.January, 1, 1, 1, 1, 1, time.UTC).Unix(),
  67. clock: clock.NewFakeClock(time.Date(2015, time.February, 1, 1, 1, 1, 1, time.UTC)),
  68. want: int64(2678400),
  69. },
  70. {
  71. name: "Future Month. Should be -Month",
  72. lastSync: time.Date(2015, time.February, 1, 1, 1, 1, 1, time.UTC).Unix(),
  73. clock: clock.NewFakeClock(time.Date(2015, time.January, 1, 1, 1, 1, 2, time.UTC)),
  74. want: int64(-2678400),
  75. },
  76. }
  77. for _, tt := range tests {
  78. t.Run(tt.name, func(t *testing.T) {
  79. tunneler := &SSHTunneler{}
  80. assert := assert.New(t)
  81. tunneler.lastSync = tt.lastSync
  82. tunneler.clock = tt.clock
  83. assert.Equal(int64(tt.want), tunneler.SecondsSinceSync())
  84. })
  85. }
  86. }
  87. // generateTempFile creates a temporary file path
  88. func generateTempFilePath(prefix string) string {
  89. tmpPath, _ := filepath.Abs(fmt.Sprintf("%s/%s-%d", os.TempDir(), prefix, time.Now().Unix()))
  90. return tmpPath
  91. }
  92. // TestGenerateSSHKey verifies that SSH key generation does indeed
  93. // generate keys even with keys already exist.
  94. func TestGenerateSSHKey(t *testing.T) {
  95. assert := assert.New(t)
  96. privateKey := generateTempFilePath("private")
  97. publicKey := generateTempFilePath("public")
  98. // Make sure we have no test keys laying around
  99. os.Remove(privateKey)
  100. os.Remove(publicKey)
  101. // Pass case: Sunny day case
  102. err := generateSSHKey(privateKey, publicKey)
  103. assert.NoError(err, "generateSSHKey should not have retuend an error: %s", err)
  104. // Pass case: PrivateKey exists test case
  105. os.Remove(publicKey)
  106. err = generateSSHKey(privateKey, publicKey)
  107. assert.NoError(err, "generateSSHKey should not have retuend an error: %s", err)
  108. // Pass case: PublicKey exists test case
  109. os.Remove(privateKey)
  110. err = generateSSHKey(privateKey, publicKey)
  111. assert.NoError(err, "generateSSHKey should not have retuend an error: %s", err)
  112. // Make sure we have no test keys laying around
  113. os.Remove(privateKey)
  114. os.Remove(publicKey)
  115. // TODO: testing error cases where the file can not be removed?
  116. }
  117. type FakeTunneler struct {
  118. SecondsSinceSyncValue int64
  119. SecondsSinceSSHKeySyncValue int64
  120. }
  121. func (t *FakeTunneler) Run(AddressFunc) {}
  122. func (t *FakeTunneler) Stop() {}
  123. func (t *FakeTunneler) Dial(ctx context.Context, net, addr string) (net.Conn, error) { return nil, nil }
  124. func (t *FakeTunneler) SecondsSinceSync() int64 { return t.SecondsSinceSyncValue }
  125. func (t *FakeTunneler) SecondsSinceSSHKeySync() int64 { return t.SecondsSinceSSHKeySyncValue }
  126. // TestIsTunnelSyncHealthy verifies that the 600 second lag test
  127. // is honored.
  128. func TestIsTunnelSyncHealthy(t *testing.T) {
  129. tunneler := &FakeTunneler{}
  130. // Pass case: 540 second lag
  131. tunneler.SecondsSinceSyncValue = 540
  132. healthFn := TunnelSyncHealthChecker(tunneler)
  133. err := healthFn(nil)
  134. assert.NoError(t, err, "IsTunnelSyncHealthy() should not have returned an error.")
  135. // Fail case: 720 second lag
  136. tunneler.SecondsSinceSyncValue = 720
  137. err = healthFn(nil)
  138. assert.Error(t, err, "IsTunnelSyncHealthy() should have returned an error.")
  139. }