Skip to content
This repository was archived by the owner on Dec 16, 2022. It is now read-only.

Commit 6f7fdeb

Browse files
author
Paulo Gomes
committed
Run tests against local git server
Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
1 parent 3a709d1 commit 6f7fdeb

File tree

8 files changed

+447
-111
lines changed

8 files changed

+447
-111
lines changed

Dockerfile.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ RUN xx-verify --static static-test-runner
109109
# using the `RUN` statement.
110110
FROM ${BASE_VARIANT}
111111

112+
RUN apk add git
113+
112114
WORKDIR /root/smoketest
113115
COPY tests/smoketest/keys /root/smoketest/keys
114116
COPY --from=build \

tests/smoketest/go.mod

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,42 @@ go 1.17
55
require github.com/libgit2/git2go/v33 v33.0.6
66

77
require (
8-
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c // indirect
9-
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
8+
github.com/Microsoft/go-winio v0.4.17 // indirect
9+
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
10+
github.com/acomagu/bufpipe v1.0.3 // indirect
11+
github.com/emirpasic/gods v1.12.0 // indirect
12+
github.com/fluxcd/pkg/gittestserver v0.5.0 // indirect
13+
github.com/fluxcd/pkg/ssh v0.3.1 // indirect
14+
github.com/fluxcd/source-controller v0.20.1 // indirect
15+
github.com/go-git/gcfg v1.5.0 // indirect
16+
github.com/go-git/go-billy/v5 v5.3.1 // indirect
17+
github.com/go-git/go-git/v5 v5.4.2 // indirect
18+
github.com/go-logr/logr v1.2.2 // indirect
19+
github.com/gogo/protobuf v1.3.2 // indirect
20+
github.com/google/go-cmp v0.5.6 // indirect
21+
github.com/google/gofuzz v1.2.0 // indirect
22+
github.com/imdario/mergo v0.3.12 // indirect
23+
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
24+
github.com/json-iterator/go v1.1.12 // indirect
25+
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
26+
github.com/mitchellh/go-homedir v1.1.0 // indirect
27+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
28+
github.com/modern-go/reflect2 v1.0.2 // indirect
29+
github.com/satori/go.uuid v1.2.0 // indirect
30+
github.com/sergi/go-diff v1.1.0 // indirect
31+
github.com/sosedoff/gitkit v0.2.1-0.20200818155723-72ebbcf5056d // indirect
32+
github.com/xanzy/ssh-agent v0.3.0 // indirect
33+
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
34+
golang.org/x/net v0.0.0-20211215060638-4ddde0e984e9 // indirect
35+
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect
36+
golang.org/x/text v0.3.7 // indirect
37+
gopkg.in/inf.v0 v0.9.1 // indirect
38+
gopkg.in/warnings.v0 v0.1.2 // indirect
39+
gopkg.in/yaml.v2 v2.4.0 // indirect
40+
k8s.io/api v0.23.1 // indirect
41+
k8s.io/apimachinery v0.23.1 // indirect
42+
k8s.io/klog/v2 v2.30.0 // indirect
43+
k8s.io/utils v0.0.0-20211208161948-7d6a63dca704 // indirect
44+
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
45+
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
1046
)

tests/smoketest/go.sum

Lines changed: 314 additions & 1 deletion
Large diffs are not rendered by default.

tests/smoketest/keys/id_ed25519

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/smoketest/keys/id_ed25519.pub

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/smoketest/keys/id_rsa

Lines changed: 0 additions & 49 deletions
This file was deleted.

tests/smoketest/keys/id_rsa.pub

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/smoketest/main.go

Lines changed: 93 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,89 +2,132 @@ package main
22

33
import (
44
"C"
5-
"log"
6-
5+
"bufio"
76
"fmt"
7+
"io"
88
"io/ioutil"
9+
"log"
10+
"net"
11+
"net/url"
912
"os"
13+
"path/filepath"
14+
"strings"
15+
"time"
1016

1117
// git2go must be aligned with libgit2 version:
1218
// https://github.com/libgit2/git2go#which-go-version-to-use
1319
git2go "github.com/libgit2/git2go/v33"
14-
)
15-
import (
16-
"bufio"
17-
"io"
18-
"net"
19-
"path/filepath"
20-
"strings"
2120

22-
"golang.org/x/crypto/ssh"
21+
"github.com/fluxcd/pkg/gittestserver"
22+
"github.com/fluxcd/pkg/ssh"
23+
"github.com/fluxcd/source-controller/pkg/git"
24+
cryptossh "golang.org/x/crypto/ssh"
2325
"golang.org/x/crypto/ssh/knownhosts"
2426
)
2527

26-
const keysDir = "/root/smoketest/keys"
27-
const host = "github.com"
28-
29-
// ssh-keyscan -t ecdsa github.com
30-
const knownHost_ecdsa = `# github.com:22 SSH-2.0-babeld-b6e6da7b
31-
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=`
32-
33-
// fingerprints can be validated against:
34-
// https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
35-
36-
// TODO: setup SSH test servers to force and test rsa/ed25519 support
37-
// ssh-keyscan -t rsa github.com
38-
const knownHost_rsa = `# github.com:22 SSH-2.0-babeld-b6e6da7b
39-
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==`
40-
41-
// ssh-keyscan -t ed25519 github.com
42-
const knownHost_ed25519 = `# github.com:22 SSH-2.0-babeld-b6e6da7b
43-
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl`
28+
const testsDir = "/root/tests"
4429

4530
func main() {
4631
fmt.Println("Running tests...")
47-
os.MkdirAll("/root/tests", 0o755)
32+
os.MkdirAll(testsDir, 0o755)
33+
defer os.RemoveAll(testsDir)
34+
35+
repoPath := "test.git"
36+
server := createTestServer(repoPath)
37+
if err := server.StartHTTP(); err != nil {
38+
panic(fmt.Errorf("StartHTTP: %w", err))
39+
}
40+
defer server.StopHTTP()
4841

42+
httpRepoURL := fmt.Sprintf("%s/%s", server.HTTPAddressWithCredentials(), repoPath)
4943
test("HTTPS clone with no options",
50-
"/root/tests/https-clone-no-options",
51-
"https://github.com/fluxcd/golang-with-libgit2",
44+
filepath.Join(testsDir, "/https-clone-no-options"),
45+
httpRepoURL,
5246
&git2go.CloneOptions{Bare: true})
5347

48+
if err := server.ListenSSH(); err != nil {
49+
panic(fmt.Errorf("listenSSH: %w", err))
50+
}
51+
go func() {
52+
server.StartSSH()
53+
}()
54+
defer server.StopSSH()
55+
56+
u, err := url.Parse(server.SSHAddress())
57+
if err != nil {
58+
panic(fmt.Errorf("ssh url Parse: %w", err))
59+
}
60+
knownHosts, err := ssh.ScanHostKey(u.Host, 5*time.Second)
61+
if err != nil {
62+
panic(fmt.Errorf("scan host key: %w", err))
63+
}
64+
65+
sshRepoURL := fmt.Sprintf("%s/%s", server.SSHAddress(), repoPath)
66+
67+
rsa, err := ssh.NewRSAGenerator(4096).Generate()
68+
if err != nil {
69+
panic(fmt.Errorf("generating rsa key: %w", err))
70+
}
71+
5472
test("SSH clone with rsa key",
55-
"/root/tests/ssh-clone-rsa",
56-
"git@github.com:pjbgf/pkg.git",
73+
filepath.Join(testsDir, "/ssh-clone-rsa"),
74+
sshRepoURL,
5775
&git2go.CloneOptions{
5876
Bare: true,
5977
FetchOptions: git2go.FetchOptions{
6078
RemoteCallbacks: git2go.RemoteCallbacks{
6179
CredentialsCallback: func(url string, username string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) {
62-
credential, e := git2go.NewCredentialSSHKey("git", keyPath("id_rsa.pub"), keyPath("id_rsa"), "")
63-
return credential, e
80+
return git2go.NewCredentialSSHKeyFromMemory("git",
81+
string(rsa.PublicKey), string(rsa.PrivateKey), "")
6482
},
65-
CertificateCheckCallback: knownHostsCallback(host, []byte(knownHost_ecdsa)),
83+
CertificateCheckCallback: knownHostsCallback(u.Host, knownHosts),
6684
},
67-
}})
85+
},
86+
})
6887

69-
//TODO: Add test ssh server to remove dependency on having a repo with specific keys registered.
88+
ed25519, err := ssh.NewEd25519Generator().Generate()
89+
if err != nil {
90+
panic(fmt.Errorf("generating ed25519 key: %w", err))
91+
}
7092
test("SSH clone with ed25519 key",
71-
"/root/tests/ssh-clone-ed25519",
72-
"git@github.com:pjbgf/pkg.git",
93+
filepath.Join(testsDir, "/ssh-clone-ed25519"),
94+
sshRepoURL,
7395
&git2go.CloneOptions{
7496
Bare: true,
7597
FetchOptions: git2go.FetchOptions{
7698
RemoteCallbacks: git2go.RemoteCallbacks{
7799
CredentialsCallback: func(url string, username string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) {
78-
credential, e := git2go.NewCredentialSSHKey("git", keyPath("id_ed25519.pub"), keyPath("id_ed25519"), "")
79-
return credential, e
100+
return git2go.NewCredentialSSHKeyFromMemory("git",
101+
string(ed25519.PublicKey), string(ed25519.PrivateKey), "")
80102
},
81-
CertificateCheckCallback: knownHostsCallback(host, []byte(knownHost_ecdsa)),
103+
CertificateCheckCallback: knownHostsCallback(u.Host, knownHosts),
82104
},
83-
}})
105+
},
106+
})
107+
108+
//TODO: Expand tests to consider supported algorithms/hashes for hostKey verification.
84109
}
85110

86-
func keyPath(keyName string) string {
87-
return filepath.Join(keysDir, keyName)
111+
func createTestServer(repoPath string) *gittestserver.GitServer {
112+
fmt.Println("Creating gitserver for SSH tests...")
113+
server, err := gittestserver.NewTempGitServer()
114+
if err != nil {
115+
panic(fmt.Errorf("creating git test server: %w", err))
116+
}
117+
defer os.RemoveAll(server.Root())
118+
119+
server.Auth("test-user", "test-pswd")
120+
server.AutoCreate()
121+
server.KeyDir(filepath.Join(server.Root(), "keys"))
122+
123+
os.MkdirAll("testdata/git/repo", 0o755)
124+
os.WriteFile("testdata/git/repo/test123", []byte("test..."), 0o644)
125+
os.WriteFile("testdata/git/repo/test321", []byte("test2..."), 0o644)
126+
127+
if err = server.InitRepo("testdata/git/repo", git.DefaultBranch, repoPath); err != nil {
128+
panic(fmt.Errorf("InitRepo: %w", err))
129+
}
130+
return server
88131
}
89132

90133
func test(description, targetDir, repoURI string, cloneOptions *git2go.CloneOptions) {
@@ -150,14 +193,14 @@ func knownHostsCallback(host string, knownHosts []byte) git2go.CertificateCheckC
150193

151194
type knownKey struct {
152195
hosts []string
153-
key ssh.PublicKey
196+
key cryptossh.PublicKey
154197
}
155198

156199
func parseKnownHosts(s string) ([]knownKey, error) {
157200
var knownHosts []knownKey
158201
scanner := bufio.NewScanner(strings.NewReader(s))
159202
for scanner.Scan() {
160-
_, hosts, pubKey, _, _, err := ssh.ParseKnownHosts(scanner.Bytes())
203+
_, hosts, pubKey, _, _, err := cryptossh.ParseKnownHosts(scanner.Bytes())
161204
if err != nil {
162205
// Lines that aren't host public key result in EOF, like a comment
163206
// line. Continue parsing the other lines.
@@ -188,8 +231,8 @@ func (k knownKey) matches(host string, hostkey git2go.HostkeyCertificate) bool {
188231
}
189232

190233
if hostkey.Kind&git2go.HostkeySHA256 > 0 {
191-
knownFingerprint := ssh.FingerprintSHA256(k.key)
192-
returnedFingerprint := ssh.FingerprintSHA256(hostkey.SSHPublicKey)
234+
knownFingerprint := cryptossh.FingerprintSHA256(k.key)
235+
returnedFingerprint := cryptossh.FingerprintSHA256(hostkey.SSHPublicKey)
193236

194237
fmt.Printf("known and found fingerprints:\n%q\n%q\n",
195238
knownFingerprint,

0 commit comments

Comments
 (0)