Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Feature: Application Boxes in Indexer #1168

Merged
merged 56 commits into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
4d86e74
New Feature: Indexer Application Box Ingestion (#1067)
tzaffi Aug 9, 2022
5681adb
Update go-algorand submodule (Remove “contact us” from box name misma…
Aug 9, 2022
ec18e29
Merge branch 'develop' into integration/boxes
Aug 9, 2022
7aa7f2f
errant extra comma in comment
tzaffi Aug 10, 2022
06ec61a
re-point submodule to lateast feature/avm-box commit
Aug 22, 2022
89283d7
Merge branch 'develop' into integration/boxes
Aug 22, 2022
9303c83
expose max_s3_keys haystack size in firstFromS3's needle search and t…
Aug 22, 2022
3570a16
Revert "expose max_s3_keys haystack size in firstFromS3's needle sear…
Aug 22, 2022
2e2b504
point to a newer box inclusive tar ball
Aug 23, 2022
ab0208c
Merge branch 'develop' into integration/boxes
Aug 23, 2022
cd08d66
Merge branch 'develop' into integration/boxes
Sep 1, 2022
e63df7d
update go-algorand submodule to feature/avm-box latest
Sep 2, 2022
f70ed58
update go.mod/sum to adjust for breakout of avm-abi from go-algorand
Sep 2, 2022
ae841ae
Merge branch 'develop' into integration/boxes
Sep 8, 2022
a759ca5
temporary: point to E2E test tarball to containing boxes
Sep 8, 2022
be68a93
update submodule
Sep 13, 2022
1a8b465
update submodule
Sep 13, 2022
5f199ed
Merge branch 'develop' of github.com:algorand/indexer into develop
Sep 14, 2022
4881e51
Merge branch 'develop' into integration/boxes
Sep 14, 2022
4bdc0a0
update submodule
Sep 14, 2022
d98ae7e
Change *string to ledgercore.ValueDelta{Data:} in kvmods (#1224)
tzaffi Sep 14, 2022
64a6462
New Feature: Lookup Boxes by app-id + Name and Search Boxes by app-id…
tzaffi Sep 14, 2022
32df6f8
Go Embed the TEAL Program (#1227)
tzaffi Sep 15, 2022
e58ccd3
update submodule
Sep 16, 2022
2864669
Merge remote-tracking branch 'refs/remotes/origin/integration/boxes' …
Sep 16, 2022
0443366
Update idb/postgres/postgres_boxes_test.go
tzaffi Sep 16, 2022
4dba1aa
Update api/handlers. Go
tzaffi Sep 16, 2022
da42502
per CR suggestion - amend fixtures test
Sep 16, 2022
0d5191b
per CR suggestion - remove ineffective assertion
Sep 16, 2022
ea4fc7a
response to CR comments - simplify SQL hardcodeing to ASC
Sep 16, 2022
35e87fa
fix inaccurate comment
Sep 16, 2022
4affdb1
Don't 404 on Boxes Search when there's No App (#1239)
tzaffi Sep 23, 2022
260786f
Fix inaccurate BoxesResponse next-token documentation (#1240)
jasonpaulos Sep 23, 2022
37f4120
Merge branch 'develop' into integration/boxes
Oct 3, 2022
62e41a8
merge and re-generate
Oct 3, 2022
a47ce18
Merge remote-tracking branch 'refs/remotes/origin/integration/boxes' …
Oct 3, 2022
c065e1e
regenerate
Oct 3, 2022
5d5fc5b
update submodule
Oct 3, 2022
193dbc8
Merge branch 'develop' into integration/boxes
Oct 5, 2022
1eae85f
latest go-algorand
Oct 11, 2022
bba69ef
Merge branch 'develop' into integration/boxes
Oct 11, 2022
b72192f
point to latest e2e tarball with boxes
Oct 11, 2022
c65dd10
Merge branch 'develop' into integration/boxes
Oct 26, 2022
239e6d6
latest go-algorand
Oct 26, 2022
ed83375
following go-algorand changes: KvValueDelta and []byte instead of Val…
Oct 26, 2022
9d93edc
test updates
Oct 27, 2022
3d4b6f0
update submodule
Oct 27, 2022
6deb9b3
latest tarball
Oct 28, 2022
7de386f
Update .circleci/config.yml
tzaffi Oct 31, 2022
8745cf3
update go-algorand latest from master
Nov 1, 2022
eddb0d0
pin E2E test to the last rel/nightly
Nov 1, 2022
bda577c
Merge remote-tracking branch 'refs/remotes/origin/integration/boxes' …
Nov 1, 2022
5d1a24c
update submodule with lint fix
Nov 1, 2022
21ac00c
go mod tidy for latest msgp
Nov 1, 2022
802bc02
once again that sneaky EOL
Nov 1, 2022
acec7c4
update go-algorand some more - including catchpoint fix
Nov 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
go_version:
type: string
environment:
CI_E2E_FILENAME: "fad05790/rel-nightly"
CI_E2E_FILENAME: "faab6dcf/rel-nightly"
steps:
- go/install:
version: << parameters.go_version >>
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ tmp/
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Output of fixtures_test.go
_*.json

# Dependency directories (remove the comment below to include it)
# vendor/

Expand All @@ -29,6 +32,9 @@ __pycache__
# jetbrains IDE
.idea

# VS Code
.vscode

.deb_tmp
.tar_tmp
*.deb
Expand Down
102 changes: 102 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ We are using a documentation driven process.
The API is defined using [OpenAPI v2](https://swagger.io/specification/v2/) in **indexer.oas2.yml**.

## Updating REST API

The Makefile will install our fork of **oapi-codegen**, use `make oapi-codegen` to install it directly.

1. Document your changes by editing **indexer.oas2.yml**
Expand All @@ -20,3 +21,104 @@ Specifically, `uint64` types aren't strictly supported by OpenAPI. So we added a
## Why do we have indexer.oas2.yml and indexer.oas3.yml?

We chose to maintain V2 and V3 versions of the spec because OpenAPI v3 doesn't seem to be widely supported. Some tools worked better with V3 and others with V2, so having both available has been useful. To reduce developer burdon, the v2 specfile is automatically converted v3 using [converter.swagger.io](http://converter.swagger.io/).

# Fixtures Test
## What is a **Fixtures Test**?

Currently (September 2022) [fixtures_test.go](./fixtures_test.go) is a library that allows testing Indexer's router to verify that endpoints accept parameters and respond as expected, and guard against future regressions. [app_boxes_fixtures_test.go](./app_boxes_fixtures_test.go) is an example _fixtures test_ and is the _creator_ of the fixture [boxes.json](./test_resources/boxes.json).

A fixtures test

1. is defined by a go-slice called a _Seed Fixture_ e.g. [var boxSeedFixture](https://github.com/algorand/indexer/blob/b5025ad640fabac0d778b4cac60d558a698ed560/api/app_boxes_fixtures_test.go#L302-L692) which contains request information for making HTTP requests against an Indexer server
2. iterates through the slice, making each of the defined requests and generating a _Live Fixture_
3. reads a _Saved Fixture_ from a json file e.g. [boxes.json](./test_resources/boxes.json)
4. persists the _Live Fixture_ to a json file not in source control
5. asserts that the _Saved Fixture_ is equal to the _Live Fixture_

In reality, because we always want to save the _Live Fixture_ before making assertions that could fail the test and pre-empt saving, steps (3) and (4) happen in the opposite order.

## What's the purpose of a Fixtures Test?

A fixtures test should allow one to quickly stand up an end-to-end test to validate that Indexer endpoints are working as expected. After Indexer's state is programmatically set up, it's easy to add new requests and verify that the responses look exactly as expected. Once you're satisfied that the responses are correct, it's easy to _freeze_ the test and guard against future regressions.
## What does a **Fixtures Test Function** Look Like?

[func TestBoxes](https://github.com/algorand/indexer/blob/b5025ad640fabac0d778b4cac60d558a698ed560/api/app_boxes_fixtures_test.go#L694_L704) shows the basic structure of a fixtures test.

1. `setupIdbAndReturnShutdownFunc()` is called to set up the Indexer database
* this isn't expected to require modification
2. `setupLiveBoxes()` is used to prepare the local ledger and process blocks in order to bring Indexer into a particular state
* this will always depend on what the test is trying to achieve
* in this case, an app was used to create and modify a set of boxes which are then queried against
* it is conceivable that instead of bringing Indexer into a particular state, the responses from the DB or even the handler may be mocked, so we could have had `setupLiveBoxesMocker()` instead of `setupLiveBoxes()`
3. `setupLiveServerAndReturnShutdownFunc()` is used to bring up an instance of a real Indexer.
* this shouldn't need to be modified; however, if running in parallel and making assertions that conflict with other tests, you may need to localize the variable `fixtestListenAddr` and run on a separate port
* if running a mock server instead, a different setup function would be needed
4. `validateLiveVsSaved()` runs steps (1) through (5) defined in the previous section
* this is designed to be generic and ought not require much modification going forward


## Which Endpoints are Currently _Testable_ in a Fixtures Test?

Endpoints defined in [proverRoutes](https://github.com/algorand/indexer/blob/b955a31b10d8dce7177383895ed8e57206d69f67/api/fixtures_test.go#L232-L263) are testable.

Currently (September 2022) these are:

* `/v2/accounts`
* `/v2/applications`
* `/v2/applications/:application-id`
* `/v2/applications/:application-id/box`
* `/v2/applications/:application-id/boxes`

## How to Introduce a New Fixtures Test for an _Already Testable_ Endpoint?

To set up a new test for endpoints defined above one needs to:

### 1. Define a new _Seed Fixture_

For example, consider

```go
var boxSeedFixture = fixture{
File: "boxes.json",
Owner: "TestBoxes",
Frozen: true,
Cases: []testCase{
// /v2/accounts - 1 case
{
Name: "What are all the accounts?",
Request: requestInfo{
Path: "/v2/accounts",
Params: []param{},
},
},
...
```

A seed fixture is a `struct` with fields
* `File` (_required_) - the name in [test_resources](./test_resources/) where the fixture is read from (and written to with an `_` prefix)
* `Owner` (_recommended_) - a name to define which test "owns" the seed
* `Frozen` (_required_) - set _true_ when you need to run assertions of the _Live Fixture_ vs. the _Saved Fixture_. For tests to pass, it needs to be set _true_.
* `Cases` - the slice of `testCase`s. Each of these has the fields:
* `Name` (_required_) - an identifier for the test case
* `Request` (_required_) - a `requestInfo` struct specifying:
* `Path` (_required_) - the path to be queried
* `Params` (_required but may be empty_) - the slice of parameters (strings `name` and `value`) to be appended to the path
### 2. Define a new _Indexer State_ Setup Function

There are many examples of setting up state that can be emulated. For example:
* [setupLiveBoxes()](https://github.com/algorand/indexer/blob/b5025ad640fabac0d778b4cac60d558a698ed560/api/app_boxes_fixtures_test.go#L43) for application boxes
* [TestApplicationHandlers()](https://github.com/algorand/indexer/blob/3a9095c2b5ee25093708f980445611a03f2cf4e2/api/handlers_e2e_test.go#L93) for applications
* [TestBlockWithTransactions()](https://github.com/algorand/indexer/blob/800cb135a0c6da0109e7282acf85cbe1961930c6/idb/postgres/postgres_integration_test.go#L339) setup state consisting of a set of basic transactions

## How to Make a _New Endpoint_ Testable by Fixtures Tests?

There are 2 steps:

1. Implement a new function _witness generator_ aka [prover function](https://github.com/algorand/indexer/blob/b955a31b10d8dce7177383895ed8e57206d69f67/api/fixtures_test.go#L103) of type `func(responseInfo) (interface{}, *string)` as examplified in [this section](https://github.com/algorand/indexer/blob/b955a31b10d8dce7177383895ed8e57206d69f67/api/fixtures_test.go#L107-L200). Such a function is supposed to parse an Indexer response's body into a generated model. Currently, all provers are boilerplate, and with generics, it's expected that this step will no longer be necessary (this [POC](https://github.com/tzaffi/indexer/blob/generic-boxes/api/fixtures_test.go#L119-L155) shows how it would be done with generics).
2. Define a new route in the [proverRoutes struct](https://github.com/algorand/indexer/blob/b955a31b10d8dce7177383895ed8e57206d69f67/api/fixtures_test.go#L232_L263). This is a tree structure which is traversed by splitting a path using `/` and eventually reaching a leaf which consists of a `prover` as defined in #1.

For example, to enable the endpoint `GET /v2/applications/{application-id}/logs` for fixtures test, one need only define a `logsProof` witness generator and have it mapped in `proverRoutes` under:

```
proverRoutes.parts["v2"].parts["applications"].parts[":application-id"].parts["logs"] = logsProof
```
Loading