Compare commits
3 commits
71764dd6fa
...
3c9867b75b
Author | SHA1 | Date | |
---|---|---|---|
3c9867b75b | |||
e3cb739db5 | |||
4cc757d550 |
26 changed files with 477 additions and 56 deletions
|
@ -1,11 +1,11 @@
|
|||
root = "./src"
|
||||
root = "."
|
||||
tmp_dir = "tmp"
|
||||
|
||||
[build]
|
||||
bin = "./tmp/main"
|
||||
cmd = "go build -o ./tmp/main ./src/."
|
||||
delay = 1000
|
||||
exclude_dir = ["assets", "tmp", "vendor"]
|
||||
exclude_dir = ["tmp", "vendor", "ui/dist", "ui/node_modules", "ui/src"]
|
||||
exclude_file = []
|
||||
exclude_regex = []
|
||||
exclude_unchanged = false
|
||||
|
|
|
@ -18,6 +18,7 @@ linters:
|
|||
linters-settings:
|
||||
lll:
|
||||
line-length: 88
|
||||
tab-width: 4
|
||||
gocognit:
|
||||
min-complexity: 10
|
||||
nestif:
|
||||
|
|
17
go.mod
17
go.mod
|
@ -9,10 +9,21 @@ require (
|
|||
github.com/gin-contrib/cors v1.3.1
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
github.com/go-errors/errors v1.4.1 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
|
53
go.sum
53
go.sum
|
@ -2,6 +2,7 @@ code.thetadev.de/TSGRain/ginzip v0.1.1 h1:+X0L6qumEZiKYSLmM+Q0LqKVHsKvdcg4CVzsEp
|
|||
code.thetadev.de/TSGRain/ginzip v0.1.1/go.mod h1:BH7VkvpP83vPRyMQ8rLIjKycQwGzF+/mFV0BKzg+BuA=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -29,31 +30,42 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
|||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -67,8 +79,8 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs
|
|||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -76,21 +88,32 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -48,27 +48,47 @@ const statusJson = `{"compatible":"TSGRain","variant":"dev","booted":"A",` +
|
|||
`{"class":"rootfs","device":"/dev/mmcblk0p2","type":"ext4","bootname":"A",` +
|
||||
`"state":"booted","parent":null,"mountpoint":"/","boot_status":"good"}}]}`
|
||||
|
||||
func printLinesWithDelay(lines string) {
|
||||
func printLinesWithDelay(lines string, delay time.Duration) {
|
||||
for _, line := range strings.Split(lines, "\n") {
|
||||
fmt.Println(line)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
time.Sleep(delay)
|
||||
}
|
||||
}
|
||||
|
||||
func getBoolEnvvar(name string) bool {
|
||||
val := strings.ToLower(os.Getenv(name))
|
||||
return val != "" && val != "false" && val != "0"
|
||||
}
|
||||
|
||||
func main() {
|
||||
arg := ""
|
||||
method := ""
|
||||
if len(os.Args) > 1 {
|
||||
arg = os.Args[1]
|
||||
method = os.Args[1]
|
||||
}
|
||||
|
||||
switch arg {
|
||||
case "fail":
|
||||
printLinesWithDelay(outputFailure)
|
||||
test := getBoolEnvvar("RAUC_MOCK_TEST")
|
||||
failure := getBoolEnvvar("RAUC_MOCK_FAIL")
|
||||
|
||||
delay := 500 * time.Millisecond
|
||||
if test {
|
||||
delay = 10 * time.Millisecond
|
||||
}
|
||||
|
||||
switch method {
|
||||
case "install":
|
||||
printLinesWithDelay(outputSuccess)
|
||||
if failure {
|
||||
printLinesWithDelay(outputFailure, delay)
|
||||
} else {
|
||||
printLinesWithDelay(outputSuccess, delay)
|
||||
}
|
||||
case "status":
|
||||
if os.Args[2] != "--output-format=json" {
|
||||
fmt.Println("output format must be json")
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(statusJson)
|
||||
default:
|
||||
fmt.Println("invalid method")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,13 @@ import (
|
|||
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/rauc"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server/mode"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server/stream"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util/mode"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("SEBRAUC " + util.Version())
|
||||
mode.Set(util.Mode)
|
||||
|
||||
if mode.IsDev() {
|
||||
fmt.Println("Test mode active - no update operations are executed.")
|
||||
|
|
|
@ -5,6 +5,7 @@ package model
|
|||
// RaucStatus contains information about the current RAUC updater status.
|
||||
//
|
||||
//swagger:model RaucStatus
|
||||
//nolint:lll
|
||||
type RaucStatus struct {
|
||||
// True if the installer is running
|
||||
// required: true
|
||||
|
|
|
@ -26,12 +26,12 @@ type Rauc struct {
|
|||
|
||||
func (r *Rauc) SetBroadcaster(bc util.Broadcaster) {
|
||||
r.bc = bc
|
||||
r.bc.Broadcast(r.GetStatusJson())
|
||||
r.bcStatus()
|
||||
}
|
||||
|
||||
func (r *Rauc) completed(updateFile string) {
|
||||
r.status.Installing = false
|
||||
r.bc.Broadcast(r.GetStatusJson())
|
||||
r.bcStatus()
|
||||
|
||||
_ = os.Remove(updateFile)
|
||||
}
|
||||
|
@ -56,9 +56,10 @@ func (r *Rauc) RunRauc(updateFile string) error {
|
|||
r.status = model.RaucStatus{
|
||||
Installing: true,
|
||||
}
|
||||
r.bc.Broadcast(r.GetStatusJson())
|
||||
r.bcStatus()
|
||||
|
||||
cmd := util.CommandFromString(fmt.Sprintf("%s install %s", util.RaucCmd, updateFile))
|
||||
cmd := util.CommandFromString(
|
||||
fmt.Sprintf("%s install %s", util.RaucCmd, updateFile))
|
||||
|
||||
readPipe, _ := cmd.StdoutPipe()
|
||||
cmd.Stderr = cmd.Stdout
|
||||
|
@ -88,7 +89,7 @@ func (r *Rauc) RunRauc(updateFile string) error {
|
|||
}
|
||||
|
||||
if hasUpdate {
|
||||
r.bc.Broadcast(r.GetStatusJson())
|
||||
r.bcStatus()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
@ -118,3 +119,7 @@ func (r *Rauc) GetStatusJson() []byte {
|
|||
statusJson, _ := json.Marshal(r.status)
|
||||
return statusJson
|
||||
}
|
||||
|
||||
func (r *Rauc) bcStatus() {
|
||||
r.bc.Broadcast(r.GetStatusJson())
|
||||
}
|
||||
|
|
116
src/rauc/rauc_test.go
Normal file
116
src/rauc/rauc_test.go
Normal file
|
@ -0,0 +1,116 @@
|
|||
package rauc
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type broadcasterMock struct {
|
||||
messages []string
|
||||
}
|
||||
|
||||
func (b *broadcasterMock) Broadcast(msg []byte) {
|
||||
b.messages = append(b.messages, string(msg))
|
||||
}
|
||||
|
||||
func TestRauc(t *testing.T) {
|
||||
//nolint:lll
|
||||
tests := []struct {
|
||||
name string
|
||||
fail string
|
||||
messages []string
|
||||
}{
|
||||
{
|
||||
name: "ok",
|
||||
fail: "",
|
||||
messages: []string{
|
||||
"{\"installing\":false,\"percent\":0,\"message\":\"\",\"last_error\":\"\",\"log\":\"\"}",
|
||||
"{\"installing\":true,\"percent\":0,\"message\":\"\",\"last_error\":\"\",\"log\":\"\"}",
|
||||
"{\"installing\":true,\"percent\":0,\"message\":\"Installing\",\"last_error\":\"\",\"log\":\"0% Installing\\n\"}",
|
||||
"{\"installing\":true,\"percent\":0,\"message\":\"Determining slot states\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n\"}",
|
||||
"{\"installing\":true,\"percent\":20,\"message\":\"Determining slot states done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":20,\"message\":\"Checking bundle\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n\"}",
|
||||
"{\"installing\":true,\"percent\":20,\"message\":\"Verifying signature\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n\"}",
|
||||
"{\"installing\":true,\"percent\":40,\"message\":\"Verifying signature done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":40,\"message\":\"Checking bundle done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":40,\"message\":\"Checking manifest contents\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n\"}",
|
||||
"{\"installing\":true,\"percent\":60,\"message\":\"Checking manifest contents done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":60,\"message\":\"Determining target install group\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n\"}",
|
||||
"{\"installing\":true,\"percent\":80,\"message\":\"Determining target install group done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":80,\"message\":\"Updating slots\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n\"}",
|
||||
"{\"installing\":true,\"percent\":80,\"message\":\"Checking slot rootfs.0\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n80% Checking slot rootfs.0\\n\"}",
|
||||
"{\"installing\":true,\"percent\":90,\"message\":\"Checking slot rootfs.0 done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n80% Checking slot rootfs.0\\n90% Checking slot rootfs.0 done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":90,\"message\":\"Copying image to rootfs.0\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n80% Checking slot rootfs.0\\n90% Checking slot rootfs.0 done.\\n90% Copying image to rootfs.0\\n\"}",
|
||||
"{\"installing\":true,\"percent\":100,\"message\":\"Copying image to rootfs.0 done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n80% Checking slot rootfs.0\\n90% Checking slot rootfs.0 done.\\n90% Copying image to rootfs.0\\n100% Copying image to rootfs.0 done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":100,\"message\":\"Updating slots done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n80% Checking slot rootfs.0\\n90% Checking slot rootfs.0 done.\\n90% Copying image to rootfs.0\\n100% Copying image to rootfs.0 done.\\n100% Updating slots done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":100,\"message\":\"Installing done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n80% Checking slot rootfs.0\\n90% Checking slot rootfs.0 done.\\n90% Copying image to rootfs.0\\n100% Copying image to rootfs.0 done.\\n100% Updating slots done.\\n100% Installing done.\\n\"}",
|
||||
"{\"installing\":false,\"percent\":100,\"message\":\"Installing done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n20% Verifying signature\\n40% Verifying signature done.\\n40% Checking bundle done.\\n40% Checking manifest contents\\n60% Checking manifest contents done.\\n60% Determining target install group\\n80% Determining target install group done.\\n80% Updating slots\\n80% Checking slot rootfs.0\\n90% Checking slot rootfs.0 done.\\n90% Copying image to rootfs.0\\n100% Copying image to rootfs.0 done.\\n100% Updating slots done.\\n100% Installing done.\\nInstalling `/app/tsgrain-update-raspberrypi3.raucb` succeeded\\n\"}",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fail",
|
||||
fail: "1",
|
||||
messages: []string{
|
||||
"{\"installing\":false,\"percent\":0,\"message\":\"\",\"last_error\":\"\",\"log\":\"\"}",
|
||||
"{\"installing\":true,\"percent\":0,\"message\":\"\",\"last_error\":\"\",\"log\":\"\"}",
|
||||
"{\"installing\":true,\"percent\":0,\"message\":\"Installing\",\"last_error\":\"\",\"log\":\"0% Installing\\n\"}",
|
||||
"{\"installing\":true,\"percent\":0,\"message\":\"Determining slot states\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n\"}",
|
||||
"{\"installing\":true,\"percent\":20,\"message\":\"Determining slot states done.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":20,\"message\":\"Checking bundle\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n\"}",
|
||||
"{\"installing\":true,\"percent\":40,\"message\":\"Checking bundle failed.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n40% Checking bundle failed.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":100,\"message\":\"Installing failed.\",\"last_error\":\"\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n40% Checking bundle failed.\\n100% Installing failed.\\n\"}",
|
||||
"{\"installing\":true,\"percent\":100,\"message\":\"Installing failed.\",\"last_error\":\"Failed to check bundle identifier: Invalid identifier. Did you pass a valid RAUC bundle?\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n40% Checking bundle failed.\\n100% Installing failed.\\nLastError: Failed to check bundle identifier: Invalid identifier. Did you pass a valid RAUC bundle?\\n\"}",
|
||||
"{\"installing\":false,\"percent\":100,\"message\":\"Installing failed.\",\"last_error\":\"Failed to check bundle identifier: Invalid identifier. Did you pass a valid RAUC bundle?\",\"log\":\"0% Installing\\n0% Determining slot states\\n20% Determining slot states done.\\n20% Checking bundle\\n40% Checking bundle failed.\\n100% Installing failed.\\nLastError: Failed to check bundle identifier: Invalid identifier. Did you pass a valid RAUC bundle?\\nInstalling /app/demo` failed\\n\"}",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
os.Setenv("RAUC_MOCK_TEST", "1")
|
||||
os.Setenv("RAUC_MOCK_FAIL", tt.fail)
|
||||
|
||||
updater := &Rauc{}
|
||||
bc := &broadcasterMock{}
|
||||
updater.SetBroadcaster(bc)
|
||||
|
||||
testfile := createTmpfile()
|
||||
|
||||
err := updater.RunRauc(testfile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Dont run multiple updates concurrently
|
||||
err = updater.RunRauc(testfile)
|
||||
assert.ErrorIs(t, err, util.ErrAlreadyRunning)
|
||||
|
||||
// Wait for updater to finish
|
||||
for updater.GetStatus().Installing {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
|
||||
assert.False(t, util.DoesFileExist(testfile), "update file was not deleted")
|
||||
|
||||
assert.Equal(t, tt.messages, bc.messages)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func createTmpfile() string {
|
||||
tmpdir, err := util.GetTmpdir()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tmpfile := filepath.Join(tmpdir, "test.raucb")
|
||||
_, err = os.Create(tmpfile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return tmpfile
|
||||
}
|
25
src/server/middleware/cache_test.go
Normal file
25
src/server/middleware/cache_test.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
router := gin.New()
|
||||
router.Use(Cache)
|
||||
router.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "HelloWorld") })
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "HelloWorld", w.Body.String())
|
||||
assert.Equal(t, "public, max-age=604800, immutable",
|
||||
w.Header().Get("Cache-Control"))
|
||||
}
|
|
@ -26,7 +26,7 @@ func ErrorHandler(isApi bool) gin.HandlerFunc {
|
|||
|
||||
func PanicHandler(isApi bool) gin.HandlerFunc {
|
||||
return nice.Recovery(func(c *gin.Context, err interface{}) {
|
||||
writeError(c, fmt.Errorf("panic: %s", err), isApi)
|
||||
writeError(c, fmt.Errorf("[PANIC] %s", err), isApi)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
140
src/server/middleware/error_handler_test.go
Normal file
140
src/server/middleware/error_handler_test.go
Normal file
|
@ -0,0 +1,140 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestErrorHandler(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
controller gin.HandlerFunc
|
||||
isApi bool
|
||||
expectResponse string
|
||||
expectStatus int
|
||||
}{
|
||||
{
|
||||
name: "error",
|
||||
controller: controllerError,
|
||||
isApi: false,
|
||||
expectResponse: "400 Bad Request: error test",
|
||||
expectStatus: http.StatusBadRequest,
|
||||
},
|
||||
{
|
||||
name: "error_api",
|
||||
controller: controllerError,
|
||||
isApi: true,
|
||||
//nolint:lll
|
||||
expectResponse: `{"error":"Bad Request","status_code":400,"msg":"error test"}`,
|
||||
expectStatus: http.StatusBadRequest,
|
||||
},
|
||||
{
|
||||
name: "generic_error",
|
||||
controller: controllerErrorGeneric,
|
||||
isApi: false,
|
||||
expectResponse: "500 Internal Server Error: generic error",
|
||||
expectStatus: http.StatusInternalServerError,
|
||||
},
|
||||
{
|
||||
name: "generic_error_api",
|
||||
controller: controllerErrorGeneric,
|
||||
isApi: true,
|
||||
//nolint:lll
|
||||
expectResponse: `{"error":"Internal Server Error","status_code":500,"msg":"generic error"}`,
|
||||
expectStatus: http.StatusInternalServerError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
router := gin.New()
|
||||
router.Use(ErrorHandler(tt.isApi))
|
||||
router.GET("/", tt.controller)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tt.expectStatus, w.Code)
|
||||
assert.Equal(t, tt.expectResponse, w.Body.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPanicHandler(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
controller gin.HandlerFunc
|
||||
isApi bool
|
||||
expectResponse string
|
||||
expectStatus int
|
||||
}{
|
||||
{
|
||||
name: "panic",
|
||||
controller: controllerPanic,
|
||||
isApi: false,
|
||||
expectResponse: "500 Internal Server Error: [PANIC] panic message",
|
||||
expectStatus: http.StatusInternalServerError,
|
||||
},
|
||||
{
|
||||
name: "panic_api",
|
||||
controller: controllerPanic,
|
||||
isApi: true,
|
||||
//nolint:lll
|
||||
expectResponse: `{"error":"Internal Server Error","status_code":500,"msg":"[PANIC] panic message"}`,
|
||||
expectStatus: http.StatusInternalServerError,
|
||||
},
|
||||
{
|
||||
name: "panic_w_error",
|
||||
controller: controllerPanicErr,
|
||||
isApi: false,
|
||||
expectResponse: "500 Internal Server Error: [PANIC] panic message in error",
|
||||
expectStatus: http.StatusInternalServerError,
|
||||
},
|
||||
{
|
||||
name: "panic_w_error_api",
|
||||
controller: controllerPanicErr,
|
||||
isApi: true,
|
||||
//nolint:lll
|
||||
expectResponse: `{"error":"Internal Server Error","status_code":500,"msg":"[PANIC] panic message in error"}`,
|
||||
expectStatus: http.StatusInternalServerError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
router := gin.New()
|
||||
router.Use(PanicHandler(tt.isApi))
|
||||
router.GET("/", tt.controller)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tt.expectStatus, w.Code)
|
||||
assert.Equal(t, tt.expectResponse, w.Body.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func controllerError(c *gin.Context) {
|
||||
c.Error(util.HttpErrNew("error test", http.StatusBadRequest))
|
||||
}
|
||||
|
||||
func controllerErrorGeneric(c *gin.Context) {
|
||||
c.Error(errors.New("generic error"))
|
||||
}
|
||||
|
||||
func controllerPanic(c *gin.Context) {
|
||||
panic("panic message")
|
||||
}
|
||||
|
||||
func controllerPanicErr(c *gin.Context) {
|
||||
panic(errors.New("panic message in error"))
|
||||
}
|
|
@ -18,10 +18,10 @@ import (
|
|||
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/model"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server/middleware"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server/mode"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server/swagger"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/sysinfo"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util/mode"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/ui"
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
@ -124,7 +124,7 @@ func (srv *SEBRAUCServer) Run() error {
|
|||
// $ref: "#/definitions/StatusMessage"
|
||||
// 409:
|
||||
// description: already running
|
||||
// schema:
|
||||
// schema:
|
||||
// $ref: "#/definitions/Error"
|
||||
// 500:
|
||||
// description: Server Error
|
||||
|
@ -154,8 +154,6 @@ func (srv *SEBRAUCServer) controllerUpdate(c *gin.Context) {
|
|||
err = srv.udater.RunRauc(updateFile)
|
||||
if err == nil {
|
||||
writeStatus(c, true, "Update started")
|
||||
} else if errors.Is(err, util.ErrAlreadyRunning) {
|
||||
writeStatus(c, false, "Updater already running")
|
||||
} else {
|
||||
c.Error(err)
|
||||
return
|
||||
|
|
|
@ -20,7 +20,7 @@ func Test_Execute(t *testing.T) {
|
|||
case <-execution:
|
||||
// expected
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Fatal("fExecute should be executed once")
|
||||
t.Fatal("Execute should be executed once")
|
||||
}
|
||||
|
||||
select {
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server/mode"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util/mode"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
@ -146,7 +146,8 @@ func newUpgrader(allowedWebSocketOrigins []string) *websocket.Upgrader {
|
|||
func compileAllowedWebSocketOrigins(allowedOrigins []string) []*regexp.Regexp {
|
||||
var compiledAllowedOrigins []*regexp.Regexp
|
||||
for _, origin := range allowedOrigins {
|
||||
compiledAllowedOrigins = append(compiledAllowedOrigins, regexp.MustCompile(origin))
|
||||
compiledAllowedOrigins = append(compiledAllowedOrigins,
|
||||
regexp.MustCompile(origin))
|
||||
}
|
||||
|
||||
return compiledAllowedOrigins
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/server/mode"
|
||||
"code.thetadev.de/TSGRain/SEBRAUC/src/util/mode"
|
||||
"github.com/fortytw2/leaktest"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
|
|
|
@ -216,6 +216,8 @@ paths:
|
|||
$ref: "#/definitions/StatusMessage"
|
||||
"409":
|
||||
description: already running
|
||||
schema:
|
||||
$ref: "#/definitions/Error"
|
||||
"500":
|
||||
description: Server Error
|
||||
schema:
|
||||
|
|
44
src/server/swagger/swagger_test.go
Normal file
44
src/server/swagger/swagger_test.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package swagger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSwagger(t *testing.T) {
|
||||
router := gin.New()
|
||||
Register(router)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/api/swagger/", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, swaggerHtml, w.Body.Bytes())
|
||||
assert.NotEmpty(t, w.Header().Get("Cache-Control"))
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest("GET", "/api/swagger/swagger.yaml", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, swaggerYaml, w.Body.Bytes())
|
||||
assert.NotEmpty(t, w.Header().Get("Cache-Control"))
|
||||
}
|
||||
|
||||
func TestSwaggerData(t *testing.T) {
|
||||
assert.True(t, bytes.Contains(swaggerHtml,
|
||||
[]byte("https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js")),
|
||||
"HTML data missing",
|
||||
)
|
||||
|
||||
assert.True(t, bytes.Contains(swaggerYaml,
|
||||
[]byte("REST API for the SEBRAUC firmware updater")),
|
||||
"YAML data missing",
|
||||
)
|
||||
}
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
package util
|
||||
|
||||
import "code.thetadev.de/TSGRain/SEBRAUC/src/server/mode"
|
||||
import "code.thetadev.de/TSGRain/SEBRAUC/src/util/mode"
|
||||
|
||||
const (
|
||||
RebootCmd = "shutdown -r 0"
|
||||
RaucCmd = "rauc"
|
||||
|
||||
Mode = mode.Prod
|
||||
appmode = mode.Prod
|
||||
)
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
package util
|
||||
|
||||
import "code.thetadev.de/TSGRain/SEBRAUC/src/server/mode"
|
||||
import "code.thetadev.de/TSGRain/SEBRAUC/src/util/mode"
|
||||
|
||||
const (
|
||||
RebootCmd = "touch /tmp/sebrauc_reboot_test"
|
||||
RaucCmd = "go run code.thetadev.de/TSGRain/SEBRAUC/src/fixtures/rauc_mock"
|
||||
|
||||
Mode = mode.Dev
|
||||
appmode = mode.Dev
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrAlreadyRunning = errors.New("rauc already running")
|
||||
ErrAlreadyRunning = HttpErrNew("rauc already running", http.StatusConflict)
|
||||
ErrFileDoesNotExist = errors.New("file does not exist")
|
||||
ErrPageNotFound = HttpErrNew("page not found", http.StatusNotFound)
|
||||
)
|
||||
|
|
|
@ -11,17 +11,16 @@ const (
|
|||
TestDev = "testdev"
|
||||
)
|
||||
|
||||
var mode = Dev
|
||||
var currentMode = Dev
|
||||
|
||||
// Set sets the new mode.
|
||||
func Set(newMode string) {
|
||||
mode = newMode
|
||||
currentMode = newMode
|
||||
updateGinMode()
|
||||
}
|
||||
|
||||
// Get returns the current mode.
|
||||
func Get() string {
|
||||
return mode
|
||||
return currentMode
|
||||
}
|
||||
|
||||
// IsDev returns true if the current mode is dev mode.
|
|
@ -1,7 +1,13 @@
|
|||
package util
|
||||
|
||||
import "code.thetadev.de/TSGRain/SEBRAUC/src/util/mode"
|
||||
|
||||
var version = "dev"
|
||||
|
||||
func init() {
|
||||
mode.Set(appmode)
|
||||
}
|
||||
|
||||
func Version() string {
|
||||
return version
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ type State = {
|
|||
}
|
||||
|
||||
export default class SysinfoCard extends Component<Props, State> {
|
||||
private fetchTimeout: number | undefined
|
||||
|
||||
constructor(props?: Props | undefined, context?: any) {
|
||||
super(props, context)
|
||||
this.fetchInfo()
|
||||
|
@ -36,13 +38,12 @@ export default class SysinfoCard extends Component<Props, State> {
|
|||
this.setState({sysinfo: response.data})
|
||||
} else {
|
||||
console.log("error fetching info", response.data)
|
||||
console.log("error fetching info", response.data)
|
||||
window.setTimeout(this.fetchInfo, 3000)
|
||||
this.fetchTimeout = window.setTimeout(this.fetchInfo, 3000)
|
||||
}
|
||||
})
|
||||
.catch((reason) => {
|
||||
console.log("error fetching info", reason)
|
||||
window.setTimeout(this.fetchInfo, 3000)
|
||||
this.fetchTimeout = window.setTimeout(this.fetchInfo, 3000)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -150,6 +151,12 @@ export default class SysinfoCard extends Component<Props, State> {
|
|||
)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.fetchTimeout !== undefined) {
|
||||
window.clearTimeout(this.fetchTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.sysinfo) {
|
||||
return this.renderSysinfo()
|
||||
|
|
23
ui/ui_test.go
Normal file
23
ui/ui_test.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUI(t *testing.T) {
|
||||
router := gin.New()
|
||||
Register(router)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/", nil)
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "SEBRAUC")
|
||||
assert.NotEmpty(t, w.Header().Get("Cache-Control"))
|
||||
}
|
Loading…
Reference in a new issue