summaryrefslogtreecommitdiff
path: root/dryad/rusalka_test.go
blob: 69136ed615d5d27042dd4025cca61e0995ff7748 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 *  Copyright (c) 2017-2018 Samsung Electronics Co., Ltd 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 dryad

//go:generate mockgen -destination=muxpi_mock_test.go -package dryad git.tizen.org/tools/muxpi/sw/nanopi/stm Interface

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"os"
	"os/user"
	"time"

	"git.tizen.org/tools/boruta"
	"git.tizen.org/tools/muxpi/sw/nanopi/stm"
	gomock "github.com/golang/mock/gomock"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"golang.org/x/crypto/ssh"
)

var _ = Describe("Rusalka", func() {
	var d boruta.Dryad
	var ctrl *gomock.Controller
	var stmMock *MockInterface
	const (
		username           = "test-user"
		homeDir            = "/home/" + username
		sshDir             = homeDir + "/.ssh/"
		authorizedKeysFile = sshDir + "authorized_keys"
	)

	BeforeEach(func() {
		ctrl = gomock.NewController(GinkgoT())
		stmMock = NewMockInterface(ctrl)

		d = NewRusalka(stmMock, username, nil)
	})

	AfterEach(func() {
		ctrl.Finish()
	})

	It("should put in maintenance", func(done Done) {
		const msg = "test message"

		gomock.InOrder(
			stmMock.EXPECT().ClearDisplay(),
			stmMock.EXPECT().PrintText(uint(0), uint(0), stm.Foreground, msg),
			stmMock.EXPECT().SetLED(stm.LED1, yellow.r, yellow.g, yellow.b),
			stmMock.EXPECT().SetLED(stm.LED1, off.r, off.g, off.b),
			stmMock.EXPECT().SetLED(stm.LED2, yellow.r, yellow.g, yellow.b),
			stmMock.EXPECT().SetLED(stm.LED2, off.r, off.g, off.b),
			stmMock.EXPECT().ClearDisplay().Do(
				func() { close(done) }),
		)

		err := d.PutInMaintenance(msg)
		Expect(err).ToNot(HaveOccurred())
		d.(*Rusalka).cancelMaintenance()
	}, 4) // blinkMaintenanceLED sleeps twice for 2 seconds each time.

	It("should prepare", func() {
		u, err := user.Current()
		if err != nil {
			Skip("failed to get user info")
		}
		if u.Uid != "0" {
			Skip("must be run as root")
		}

		err = d.Prepare(nil)
		Expect(err).To(Equal(errors.New("empty public key")))
		key, err := rsa.GenerateKey(rand.Reader, 1024)
		Expect(err).ToNot(HaveOccurred())
		pubKey, err := ssh.NewPublicKey(&key.PublicKey)
		Expect(err).ToNot(HaveOccurred())
		err = d.Prepare(&pubKey)
		Expect(err).ToNot(HaveOccurred())
		Expect(sshDir).To(BeADirectory())
		Expect(authorizedKeysFile).To(BeARegularFile())
		// TODO(amistewicz): Test for file permissions
		// sshDir should have 0755 boruta-user
		// authorizedKeysFile should be owned by boruta-user
		pem.Encode(os.Stderr, &pem.Block{
			Type:  "RSA PRIVATE KEY",
			Bytes: x509.MarshalPKCS1PrivateKey(key),
		})
	})

	It("should be healthy", func() {
		stmMock.EXPECT().PowerTick(time.Second)

		err := d.Healthcheck()
		Expect(err).ToNot(HaveOccurred())
	})
})