Skip to content

Use sqlite3 as the default driver for unit tests#886

Merged
codingllama merged 11 commits intogoogle:masterfrom
codingllama:sqlite
Nov 9, 2017
Merged

Use sqlite3 as the default driver for unit tests#886
codingllama merged 11 commits intogoogle:masterfrom
codingllama:sqlite

Conversation

@codingllama
Copy link
Copy Markdown
Contributor

The testdb package adds utilities to create test databases for different
drivers. Currently, it supports sqlite3 (default) and mysql. The default driver
can be specified by the TRILLIAN_SQL_DRIVER environment variable, allowing tests
to transparently execute against different databases/drivers.

Adjustments done to existing code:

  • storage.sql declares unique constraints separately from the table declaration
    (functionally equivalent, but more portable)
  • A few constants in query strings are now quoted (eg, 'false' instead of
    false, otherwise SQLite interprets the constant as a column name)
  • Duplicate handling (isDuplicateErr) handles both MySQL and SQLite error codes
  • map_storage.go no longer distinguishes between empty and nil mapper metadata
    (SQLite writes []byte{} as NULL). (This is a positive change in many ways, as
    an empty Any proto is not valid due to having no type_url.)

A few test loops that defer-close resources had their scope reduced (using
anonymous functions), as doing so greatly reduces test duration on SQLite.

Finally, integration.GetTestDB has been completely replaced by
testdb.NewTrillianDB.

@codingllama
Copy link
Copy Markdown
Contributor Author

Fixes #456.

@codecov-io
Copy link
Copy Markdown

codecov-io commented Nov 7, 2017

Codecov Report

Merging #886 into master will decrease coverage by 0.02%.
The diff coverage is 80%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #886      +/-   ##
==========================================
- Coverage   64.45%   64.43%   -0.03%     
==========================================
  Files          91       91              
  Lines        7577     7581       +4     
==========================================
+ Hits         4884     4885       +1     
- Misses       2237     2242       +5     
+ Partials      456      454       -2
Impacted Files Coverage Δ
storage/mysql/tree_storage.go 51.65% <ø> (-1.43%) ⬇️
storage/mysql/admin_storage.go 75.29% <ø> (ø) ⬆️
storage/mysql/map_storage.go 70% <100%> (ø) ⬆️
storage/mysql/log_storage.go 75.07% <77.77%> (-0.3%) ⬇️
util/tracker.go 100% <0%> (+3.38%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 90b0e23...4d1911b. Read the comment docs.

@codingllama codingllama removed the WIP label Nov 7, 2017
@codingllama codingllama requested a review from AlCutter November 7, 2017 12:33
.travis.yml Outdated
- cd $HOME/gopath/src/github.com/google/trillian
- HAMMER_OPTS="--operations=50" ./integration/maphammer.sh 3
- |
if [[ -n "${TRILLIAN_SQL_DRIVER}" && "${TRILLIAN_SQL_DRIVER}" != sqlite3 ]]; then
Copy link
Copy Markdown
Member

@AlCutter AlCutter Nov 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"sqlite3"?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or, just to capture an IRL chat, flip this to check for mysql since that what the scripts contained in the block are expecting?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flipped and quoted.

)

func TestMapIntegration(t *testing.T) {
if provider := testdb.Default(); !provider.IsMySQL() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be a useful test helper func to share with the other tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is OK, it's not that verbose and both the Skip and the message are clearly visible in the test.

j, logID := j, logID
func() {
tx := beginLogTx(s, logID, t)
defer tx.Close()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you do this func(){}() to force the defer to run or was there another subtle reason?
If it's the former, maybe it's better to just explicitly do the tx.Close() below, 'cos the function is a bit confusing (it looks like it might go async or something).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One suggestion might be something like a func runWithTX(s, logID, f func(tx) err) err and you'd do here:

for ... {
  err := runWithTX(s, logID, func f(tx ...) err {
      numToAdd ..
      ...
      if bad {
         return errors.New(...) 
      }
      ...
      return nil
    })
    if err != nil {
      t.Error...
    }
}

and runWithTX does the

tx := beginLog...
defer tx.Close()
return f(tx)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the funcs were because of the defer-close. I went with your first suggestion and explicitly closed the tx.

I have been meaning to add runInTX methods for a while now, but in a slightly different form. I'll save those to another PR.

if diff := pretty.Compare(expectedCount, got); diff != "" {
t.Errorf("GetUnsequencedCounts() = diff -want +got:\n%s", diff)
}
func() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
);

CREATE UNIQUE INDEX TreeHeadRevisionIdx
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(curiosity) is there a material difference between this and how it was declared before?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from having an explicit name, I think it's the same.


// Provider is an object capable of creating new test databases.
type Provider struct {
Driver string
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these need comments too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

continue // skip empty lines and comments
}
if p.Driver == sqliteDriver {
line = enumRegex.ReplaceAllString(line, "VARCHAR(50)")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😭

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll assume those are happy tears. ;)

@AlCutter AlCutter self-assigned this Nov 8, 2017
@codingllama
Copy link
Copy Markdown
Contributor Author

@AlCutter: all comments addressed, PTAL.

@codingllama
Copy link
Copy Markdown
Contributor Author

Thanks! Rebased on master, that should fix Travis errors.

@codingllama codingllama merged commit 4023e5a into google:master Nov 9, 2017
@codingllama codingllama deleted the sqlite branch November 9, 2017 12:24
daviddrysdale added a commit to daviddrysdale/trillian that referenced this pull request Mar 21, 2018
This partly-reverts commit 4023e5a ("Use sqlite3 as the default
driver for unit tests (google#886)"), removing SQLite as a storage option.

In practice, having a default DB that doesn't support much of the
Trillian functionality (e.g. none of the map tests, none of the
integration tests) has inconvenienced core developers.

However, to allow the core `git clone <repo> ; go test ./...`
scenario to still work without setup dependencies, all DB-using tests
explicitly check for MySQL availability and are skipped if MySQL
is not present.
daviddrysdale added a commit to daviddrysdale/trillian that referenced this pull request Mar 21, 2018
This partly-reverts commit 4023e5a ("Use sqlite3 as the default
driver for unit tests (google#886)"), removing SQLite as a storage option.

In practice, having a default DB that doesn't support much of the
Trillian functionality (e.g. none of the map tests, none of the
integration tests) has inconvenienced core developers.

However, to allow the core `git clone <repo> ; go test ./...`
scenario to still work without setup dependencies, all DB-using tests
explicitly check for MySQL availability and are skipped if MySQL
is not present.
daviddrysdale added a commit that referenced this pull request Mar 23, 2018
This partly-reverts commit 4023e5a ("Use sqlite3 as the default
driver for unit tests (#886)"), removing SQLite as a storage option.

In practice, having a default DB that doesn't support much of the
Trillian functionality (e.g. none of the map tests, none of the
integration tests) has inconvenienced core developers.

However, to allow the core `git clone <repo> ; go test ./...`
scenario to still work without setup dependencies, all DB-using tests
explicitly check for MySQL availability and are skipped if MySQL
is not present.  A single deliberate test failure is emitted in this
situation as a reminder that many tests are being skipped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants