Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
partition,snap: add support for android boot #3324
Conversation
zyga
changed the title from
Androidboot
to
partition,snap: add support for android boot
May 16, 2017
and others
added some commits
Nov 1, 2016
| +// -*- Mode: Go; indent-tabs-mode: t -*- | ||
| + | ||
| +/* | ||
| + * Copyright (C) 2014-2017 Canonical Ltd |
| +} | ||
| + | ||
| +func (a *androidboot) GetBootVars(names ...string) (map[string]string, error) { | ||
| + out := make(map[string]string) |
chipaca
May 16, 2017
Member
furthermore: you know how big it needs to be (len(names)), so make it with that size already
| + . "gopkg.in/check.v1" | ||
| +) | ||
| + | ||
| +func mockAndroidbootFile(c *C, newPath string, mode os.FileMode) { |
zyga
May 16, 2017
Contributor
Should we not have a SetUpTest function that calls dirs.SetRootDir(c.MkDir())? This should be paired with TearDownTest that calls dirs.SetRootDir("")
| + c.Assert(err, IsNil) | ||
| +} | ||
| + | ||
| +func (s *PartitionTestSuite) makeFakeAndroidbootConfig(c *C) { |
zyga
May 16, 2017
Contributor
If this happens to be done in each test feel free to do it in SetUpTest
| +func (s *PartitionTestSuite) TestNewAndroidbootNoAndroidbootReturnsNil(c *C) { | ||
| + s.makeFakeAndroidbootConfig(c) | ||
| + | ||
| + dirs.GlobalRootDir = "/something/not/there" |
| + return err | ||
| + } | ||
| + | ||
| + rawEnv := bytes.Split(buf, []byte("\n")) |
| + l := bytes.SplitN(env, []byte("="), 2) | ||
| + // be liberal in what you accept | ||
| + if len(l) < 2 { | ||
| + continue |
| + return err | ||
| + } | ||
| + } | ||
| + |
chipaca
May 16, 2017
Member
also, one nice thing about bytes.Buffer is that you can just declare it and start using it; NewBuffer is only needed when you want to preload the buffer with something. Otherwise, just
var w bytes.Bufferand you're done (although some things will need you to pass a pointer to this, e.g. things expecting an io.Writer).
chipaca
requested changes
May 16, 2017
Very nice, thank you!
A bunch of small things to fix, mostly idiomatic and not conceptual.
| +} | ||
| + | ||
| +func (a *androidboot) GetBootVars(names ...string) (map[string]string, error) { | ||
| + out := make(map[string]string) |
chipaca
May 16, 2017
Member
furthermore: you know how big it needs to be (len(names)), so make it with that size already
| + * | ||
| + */ | ||
| + | ||
| +package partition |
chipaca
May 16, 2017
Member
can you make this package partition_test, please? (maybe use export_test.go to get to the private bits you need for testing)
| +func mockAndroidbootFile(c *C, newPath string, mode os.FileMode) { | ||
| + newpath := filepath.Join(dirs.GlobalRootDir, "/boot/androidboot") | ||
| + os.MkdirAll(newpath, os.ModePerm) | ||
| + err := ioutil.WriteFile(newPath, nil, mode) |
chipaca
May 16, 2017
Member
what exactly is this supposed to be doing? I mean, what's the intention?
(because I'm pretty sure there's something wrong)
alfonsosanchezbeato
May 17, 2017
Contributor
This creates a folder and then a new file. I think it is confusing due to a variable named newpath and another one named newPath. I have changed that.
| + | ||
| + a := newAndroidboot() | ||
| + c.Assert(a, NotNil) | ||
| + c.Assert(a, FitsTypeOf, &androidboot{}) |
chipaca
May 16, 2017
Member
in general please use Assert when something needs to be true for the rest of the test to make sense, but Check when otherwise (in this case, the second one would usually be a Check unless you were then doing a type assertion)
| + | ||
| + a := newAndroidboot() | ||
| + bootVars := map[string]string{} | ||
| + bootVars["snap_mode"] = "try" |
| + v, err := a.GetBootVars("snap_mode") | ||
| + c.Assert(err, IsNil) | ||
| + c.Check(v, HasLen, 1) | ||
| + c.Check(v["snap_mode"], Equals, "try") |
| + return err | ||
| + } | ||
| + | ||
| + rawEnv := bytes.Split(buf, []byte("\n")) |
| + l := bytes.SplitN(env, []byte("="), 2) | ||
| + // be liberal in what you accept | ||
| + if len(l) < 2 { | ||
| + continue |
| + return err | ||
| + } | ||
| + } | ||
| + |
chipaca
May 16, 2017
Member
also, one nice thing about bytes.Buffer is that you can just declare it and start using it; NewBuffer is only needed when you want to preload the buffer with something. Otherwise, just
var w bytes.Bufferand you're done (although some things will need you to pass a pointer to this, e.g. things expecting an io.Writer).
| + | ||
| +func (a *androidbootenvTestSuite) TestSet(c *C) { | ||
| + env := androidbootenv.NewEnv(a.envPath) | ||
| + c.Check(env, NotNil) |
| + | ||
| +func (a *androidbootenvTestSuite) TestSaveAndLoad(c *C) { | ||
| + env := androidbootenv.NewEnv(a.envPath) | ||
| + c.Check(env, NotNil) |
chipaca
May 16, 2017
Member
here this should probably be an Assert (otherwise all the other tests will panic)
| foundBootloader = true | ||
| default: | ||
| - return nil, fmt.Errorf(errorFormat, "bootloader must be either grub or u-boot") | ||
| + return nil, fmt.Errorf(errorFormat, "bootloader must be either grub, u-boot or android-boot") |
alfonsosanchezbeato
added some commits
May 17, 2017
mvo5
reviewed
May 17, 2017
Looks very nice, thanks for doing this work. I have some comments inside that might be worth considering. But nothing major, it looks pretty nice.
| + file, err := os.Open(a.path) | ||
| + if err != nil { | ||
| + return err | ||
| + } |
| +) | ||
| + | ||
| +// creates a new Androidboot bootloader object | ||
| +func MockNewAndroidboot() Bootloader { |
mvo5
May 17, 2017
Collaborator
(nitpick) this can probably just be NewAndroidboot() nothing is mocked/faked here its just exported for the tests.
| + | ||
| +func MockAndroidbootFile(c *C, mode os.FileMode) { | ||
| + f := &androidboot{} | ||
| + newpath := filepath.Join(dirs.GlobalRootDir, "/boot/androidboot") |
mvo5
May 17, 2017
Collaborator
(nitpick) might be easier to do: newpath := filepath.Dir(f.ConfigFile()) (or f.Dir()), then you don't need to encode the knowledge of the exact path into this test.
| +func MockAndroidbootFile(c *C, mode os.FileMode) { | ||
| + f := &androidboot{} | ||
| + newpath := filepath.Join(dirs.GlobalRootDir, "/boot/androidboot") | ||
| + os.MkdirAll(newpath, os.ModePerm) |
mvo5
May 17, 2017
Collaborator
(nitpick) I think it makes sense to get the err from os.MkdirAll() and c.Assert(err, IsNil).
mvo5
May 17, 2017
Collaborator
Also, os.ModePerm is 0777, even in its a test I would use 0755 here instead (just in case umask is funny etc).
| + | ||
| + out := make(map[string]string, len(names)) | ||
| + for _, name := range names { | ||
| + out[name] = env.Get(name) |
alfonsosanchezbeato
May 17, 2017
Contributor
Not really, it would be a bug either in snapd or in the bootloader if that happens.
| + if err := env.Load(); err != nil && !os.IsNotExist(err) { | ||
| + return err | ||
| + } | ||
| + for k, v := range values { |
| +func (g *androidbootTestSuite) SetUpTest(c *C) { | ||
| + dirs.SetRootDir(c.MkDir()) | ||
| + | ||
| + // the file needs to exist |
| +} | ||
| + | ||
| +func (s *androidbootTestSuite) TestNewAndroidbootNoAndroidbootReturnsNil(c *C) { | ||
| + dirs.SetRootDir("") |
zyga
May 17, 2017
Contributor
Except when ran on android. I would suggest you to actually keep using the temporary random directory and populate it (or not populate it perhaps) so that it has the right data for the test. This will just run it on the real system which is not what unit tests are about.
| +} | ||
| + | ||
| +func (s *androidbootTestSuite) TestSetGetBootVar(c *C) { | ||
| + a := partition.MockNewAndroidboot() |
zyga
May 17, 2017
Contributor
You can move this to the SetUpTest function as it seems to happen in all the tests.
alfonsosanchezbeato
May 17, 2017
Contributor
TestNewAndroidbootNoAndroidbootReturnsNil is unfortunately an exception.
| + "github.com/snapcore/snapd/osutil" | ||
| +) | ||
| + | ||
| +type Env struct { |
zyga
May 17, 2017
Contributor
Some documentation (tip: run golint in the directory) would help here.
| + l := strings.SplitN(scanner.Text(), "=", 2) | ||
| + // be liberal in what you accept | ||
| + if len(l) < 2 { | ||
| + logger.Noticef("WARNING: bad value while parsing %v", a.path) |
| +} | ||
| + | ||
| +func (a *androidbootenvTestSuite) TestSet(c *C) { | ||
| + env := androidbootenv.NewEnv(a.envPath) |
| +) | ||
| + | ||
| +// creates a new Androidboot bootloader object | ||
| +func MockNewAndroidboot() Bootloader { |
zyga
May 17, 2017
Contributor
This is not a mock, it's doing the real thing.
Instead do this:
var NewAndroidBoot = newAndroidBoot
(Note that I also changed the capitalization of androidboot to AndroidBoot)
| + return newAndroidboot() | ||
| +} | ||
| + | ||
| +func MockAndroidbootFile(c *C, mode os.FileMode) { |
chipaca
approved these changes
May 17, 2017
nearly there! marking approved by me as my concerns are raised by zyga and mvo already :-)
|
Thanks again for the reviews, PR refreshed after addressing comments. |
alfonsosanchezbeato
added some commits
May 17, 2017
| + } | ||
| + a.env[l[0]] = l[1] | ||
| + } | ||
| + |
zyga
May 18, 2017
Contributor
I think you need to use the scanner.Err here. See https://golang.org/src/bufio/example_test.go for examples.
| +func (a *Env) Save() error { | ||
| + var w bytes.Buffer | ||
| + | ||
| + for k, v := range a.env { |
zyga
May 18, 2017
Contributor
Do we care about deterministic output here? If so please sort the keys, and write in order.
alfonsosanchezbeato
May 18, 2017
Contributor
Not really, neither the booloader or snapd cares about the order in which the variables are stored.
| + a.env.Set("key3", "value3") | ||
| + | ||
| + err := a.env.Save() | ||
| + c.Assert(err, IsNil) |
zyga
May 18, 2017
Contributor
Can you add a trivial test that ensures the output is as you expect, as in the actual string is what we expect (deterministic)
|
PR repushed after addressing comments |
codecov-io
commented
May 18, 2017
Codecov Report
@@ Coverage Diff @@
## master #3324 +/- ##
==========================================
- Coverage 77.6% 77.59% -0.02%
==========================================
Files 364 366 +2
Lines 24956 25014 +58
==========================================
+ Hits 19368 19409 +41
- Misses 3865 3876 +11
- Partials 1723 1729 +6
Continue to review full report at Codecov.
|
zyga
approved these changes
May 19, 2017
LGTM, there are some tweaks we could do but I won't mind doing it in a follow-up.
alfonsosanchezbeato commentedMay 16, 2017
•
Edited 1 time
-
alfonsosanchezbeato
May 17, 2017
Support for android style bootloading