1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
21 "git.arvados.org/arvados.git/sdk/go/arvadostest"
25 type DockerSuite struct {
32 var _ = check.Suite(&DockerSuite{})
34 func Test(t *testing.T) { check.TestingT(t) }
36 func (s *DockerSuite) SetUpSuite(c *check.C) {
38 c.Skip("skipping docker tests in short mode")
39 } else if _, err := exec.Command("docker", "info").CombinedOutput(); err != nil {
40 c.Skip("skipping docker tests because docker is not available")
45 // The integration-testing controller listens on the loopback
46 // interface, so it won't be reachable directly from the
47 // docker container -- so here we run a proxy on 0.0.0.0 for
48 // the duration of the test.
49 hostips, err := exec.Command("hostname", "-I").Output()
50 c.Assert(err, check.IsNil)
51 s.hostip = strings.Split(strings.Trim(string(hostips), "\n"), " ")[0]
52 ln, err := net.Listen("tcp", s.hostip+":0")
53 c.Assert(err, check.IsNil)
55 proxy := httputil.NewSingleHostReverseProxy(&url.URL{Scheme: "https", Host: os.Getenv("ARVADOS_API_HOST")})
56 proxy.Transport = &http.Transport{
57 TLSClientConfig: &tls.Config{
58 InsecureSkipVerify: true,
61 s.proxysrv = &http.Server{Handler: proxy}
62 go s.proxysrv.ServeTLS(ln, "../../services/api/tmp/self-signed.pem", "../../services/api/tmp/self-signed.key")
63 proxyhost := ln.Addr().String()
65 // Build a pam module to install & configure in the docker
67 cmd := exec.Command("go", "build", "-buildmode=c-shared", "-o", s.tmpdir+"/pam_arvados.so")
68 cmd.Stdout = os.Stdout
69 cmd.Stderr = os.Stderr
71 c.Assert(err, check.IsNil)
73 // Write a PAM config file that uses our proxy as
75 confdata := fmt.Sprintf(`Name: Arvados authentication
80 [success=end default=ignore] /usr/lib/security/pam_arvados.so %s testvm2.shell insecure
82 [success=end default=ignore] /usr/lib/security/pam_arvados.so %s testvm2.shell insecure
83 `, proxyhost, proxyhost)
84 err = ioutil.WriteFile(s.tmpdir+"/conffile", []byte(confdata), 0755)
85 c.Assert(err, check.IsNil)
87 // Build the testclient program that will (from inside the
88 // docker container) configure the system to use the above PAM
89 // config, and then try authentication.
90 cmd = exec.Command("go", "build", "-o", s.tmpdir+"/testclient", "./testclient.go")
91 cmd.Stdout = os.Stdout
92 cmd.Stderr = os.Stderr
94 c.Assert(err, check.IsNil)
97 func (s *DockerSuite) TearDownSuite(c *check.C) {
102 func (s *DockerSuite) runTestClient(c *check.C, args ...string) (stdout, stderr *bytes.Buffer, err error) {
103 cmd := exec.Command("docker", append([]string{
105 "--add-host", "zzzzz.arvadosapi.com:" + s.hostip,
106 "-v", s.tmpdir + "/pam_arvados.so:/usr/lib/security/pam_arvados.so:ro",
107 "-v", s.tmpdir + "/conffile:/usr/share/pam-configs/arvados:ro",
108 "-v", s.tmpdir + "/testclient:/testclient:ro",
110 "/testclient"}, args...)...)
111 stdout = &bytes.Buffer{}
112 stderr = &bytes.Buffer{}
119 func (s *DockerSuite) TestSuccess(c *check.C) {
120 stdout, stderr, err := s.runTestClient(c, "try", "active", arvadostest.ActiveTokenV2)
121 c.Check(err, check.IsNil)
122 c.Check(stdout.String(), check.Equals, "")
123 c.Check(stderr.String(), check.Matches, `(?ms).*authentication succeeded.*`)
126 func (s *DockerSuite) TestFailure(c *check.C) {
127 for _, trial := range []struct {
132 {"bad token", "active", arvadostest.ActiveTokenV2 + "badtoken"},
133 {"empty token", "active", ""},
134 {"empty username", "", arvadostest.ActiveTokenV2},
135 {"wrong username", "wrongusername", arvadostest.ActiveTokenV2},
137 c.Logf("trial: %s", trial.label)
138 stdout, stderr, err := s.runTestClient(c, "try", trial.username, trial.token)
139 c.Check(err, check.NotNil)
140 c.Check(stdout.String(), check.Equals, "")
141 c.Check(stderr.String(), check.Matches, `(?ms).*authentication failed.*`)