diff --git a/.github/workflows/basic-checks.yml b/.github/workflows/basic-checks.yml index aba12b09..8546fd8e 100644 --- a/.github/workflows/basic-checks.yml +++ b/.github/workflows/basic-checks.yml @@ -10,24 +10,32 @@ on: jobs: lint: + env: + GOLANGCI_LINT_VERSION: v1.61.0 + name: golangci-lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-go@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 with: - go-version: "1.22.6" - - - name: Check lint - run: go fmt ./... + go-version: ^1.22 + - uses: technote-space/get-diff-action@v6.1.2 + id: git_diff + with: + PATTERNS: | + **/**.go + go.mod + go.sum + - run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION} + - name: Run golangci-lint + run: make lint unit-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-go@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 with: - go-version: "1.22.6" + go-version: ^1.22 - name: Run unit tests run: go test -v ./... diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index cb107e9b..b20d47fa 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -11,11 +11,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: "1.22.6" + go-version: ^1.22 - name: Check lint run: go fmt ./... @@ -29,11 +29,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: "1.22.6" + go-version: ^1.22 - name: Run Integration Tests run: cd tests && go test -v ./... @@ -49,11 +49,11 @@ jobs: goarch: [amd64, arm64] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: "1.22.6" + go-version: ^1.22 - name: Read enabled flags run: | diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a6297215..2da4ad8e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -18,11 +18,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: "1.22.6" + go-version: ^1.22 - name: Run Integration Tests run: cd tests && go test -v ./... diff --git a/.github/workflows/on-workflow-end.yaml b/.github/workflows/on-workflow-end.yaml index 8e33b778..698a5fc7 100644 --- a/.github/workflows/on-workflow-end.yaml +++ b/.github/workflows/on-workflow-end.yaml @@ -10,7 +10,7 @@ jobs: notify-slack: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Get Slack member IDs id: get-slack-id diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..56782cea --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,25 @@ +linters: + disable-all: false + disable: + - thelper + - varnamelen + - tagliatelle + - wrapcheck + - typecheck + errcheck: + exclude-functions: + - fmt:.* + - io/ioutil:^Read.* + - github.com/spf13/cobra:MarkFlagRequired + - github.com/spf13/viper:BindPFlag +linters-settings: + gocyclo: + min-complexity: 11 + golint: + min-confidence: 1.1 +issues: + exclude: + - composite + - 'SA1019: "golang.org/x/crypto/ripemd160" is deprecated:' # Exclude deprecated ripemd160 warning +run: + tests: false diff --git a/Makefile b/Makefile index 965e0da0..463d719f 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ release_version=$(filter-out $@,$(MAKECMDGOALS)) # Version check check_version: - @if [ "$(GO_SYSTEM_VERSION)" != "$(REQUIRE_GO_VERSION)" ]; then \ + @if [ $(shell echo "$(GO_SYSTEM_VERSION) < $(REQUIRE_GO_VERSION)" | bc -l) -eq 1 ]; then \ echo "ERROR: Go version $(REQUIRE_GO_VERSION) is required for Weave."; \ exit 1; \ fi @@ -35,6 +35,20 @@ build: check_version $(BUILDDIR) install: check_version go install -ldflags "$(LDFLAGS)" . +.PHONY: lint lint-fix + +# Run golangci-lint to check code quality +lint: check_version + @command -v golangci-lint >/dev/null 2>&1 || { echo "golangci-lint is required but not installed. Install it by following instructions at https://golangci-lint.run/welcome/install/"; exit 1; } + golangci-lint run --out-format=tab --timeout=15m + +# Run golangci-lint and automatically fix issues where possible (use with caution) +lint-fix: check_version + @echo "Warning: This will automatically modify your files to fix linting issues" + @read -p "Are you sure you want to continue? [y/N] " -n 1 -r; echo; if [[ ! $$REPLY =~ ^[Yy]$$ ]]; then exit 1; fi + @command -v golangci-lint >/dev/null 2>&1 || { echo "golangci-lint is required but not installed. Install it by following instructions at https://golangci-lint.run/welcome/install/"; exit 1; } + golangci-lint run --fix --out-format=tab --timeout=15m + test: check_version go clean -testcache go test -v ./... diff --git a/client/grpc.go b/client/grpc.go index 5046bbca..132f7bb8 100644 --- a/client/grpc.go +++ b/client/grpc.go @@ -16,9 +16,7 @@ const ( ) // GRPCClient defines the logic for making gRPC requests. -type GRPCClient struct { - conn *grpc.ClientConn -} +type GRPCClient struct{} // NewGRPCClient initializes and returns a new GRPCClient instance. func NewGRPCClient() *GRPCClient { @@ -27,9 +25,7 @@ func NewGRPCClient() *GRPCClient { // CheckHealth attempts to connect to the server and uses the reflection service to verify the server is up. func (g *GRPCClient) CheckHealth(serverAddr string) error { - if strings.HasPrefix(serverAddr, "grpc://") { - serverAddr = strings.TrimPrefix(serverAddr, "grpc://") - } + serverAddr = strings.TrimPrefix(serverAddr, "grpc://") conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { diff --git a/cmd/opinit_bots.go b/cmd/opinit_bots.go index 47c0e034..507bd36f 100644 --- a/cmd/opinit_bots.go +++ b/cmd/opinit_bots.go @@ -213,7 +213,7 @@ Valid options are [executor, challenger] eg. weave opinit-bots stop challenger`, if err != nil { return err } - fmt.Println(fmt.Sprintf("Stopped the OPinit %s bot process.", botName)) + fmt.Printf("Stopped the OPinit %s bot process.\n", botName) return nil }, } @@ -298,7 +298,7 @@ Valid options are [executor, challenger] eg. weave opinit-bots reset challenger` if err = execCmd.Run(); err != nil { return fmt.Errorf("failed to reset-db: %v", err) } - fmt.Println(fmt.Sprintf("Reset the OPinit %[1]s bot database successfully.", botName)) + fmt.Printf("Reset the OPinit %s bot database successfully.\n", botName) return nil }, } diff --git a/cosmosutils/keys.go b/cosmosutils/keys.go index 79f1661a..5033f29f 100644 --- a/cosmosutils/keys.go +++ b/cosmosutils/keys.go @@ -331,7 +331,12 @@ func addNewKeyToHermes(appName, chainId, mnemonic string) (*KeyInfo, error) { if err = io.WriteFile(tempMnemonicPath, mnemonic); err != nil { return nil, fmt.Errorf("failed to write raw tx file: %v", err) } - defer io.DeleteFile(tempMnemonicPath) + + defer func() { + if err := io.DeleteFile(tempMnemonicPath); err != nil { + fmt.Printf("failed to delete temp mnemonic file: %v", err) + } + }() cmd := exec.Command(appName, "keys", "add", "--chain", chainId, "--mnemonic-file", tempMnemonicPath) @@ -370,11 +375,11 @@ func RecoverNewHermesKey(appName, chainId, mnemonic string) (*KeyInfo, error) { } func GenerateAndReplaceHermesKey(appName, chainId string) (*KeyInfo, error) { - DeleteWeaveKeyFromHermes(appName, chainId) + _ = DeleteWeaveKeyFromHermes(appName, chainId) return GenerateAndAddNewHermesKey(appName, chainId) } func RecoverAndReplaceHermesKey(appName, chainId, mnemonic string) (*KeyInfo, error) { - DeleteWeaveKeyFromHermes(appName, chainId) + _ = DeleteWeaveKeyFromHermes(appName, chainId) return RecoverNewHermesKey(appName, chainId, mnemonic) } diff --git a/models/minitia/launch.go b/models/minitia/launch.go index 1ed2195a..b6589c45 100644 --- a/models/minitia/launch.go +++ b/models/minitia/launch.go @@ -2170,7 +2170,7 @@ func (m *DownloadCelestiaBinaryLoading) Update(msg tea.Msg) (tea.Model, tea.Cmd) state := weavecontext.PushPageAndGetState[LaunchState](m) if state.downloadedNewCelestiaBinary { - state.weave.PushPreviousResponse(styles.RenderPreviousResponse(styles.NoSeparator, fmt.Sprintf("Celestia binary has been successfully downloaded."), []string{}, "")) + state.weave.PushPreviousResponse(styles.RenderPreviousResponse(styles.NoSeparator, "Celestia binary has been successfully downloaded.", []string{}, "")) } model := NewGenerateOrRecoverSystemKeysLoading(weavecontext.SetCurrentState(m.Ctx, state)) return model, model.Init() diff --git a/models/minitia/tx.go b/models/minitia/tx.go index 64a0f083..271b928a 100644 --- a/models/minitia/tx.go +++ b/models/minitia/tx.go @@ -115,7 +115,11 @@ func (lsk *L1SystemKeys) FundAccountsWithGasStation(state *LaunchState) (*FundAc if err = io.WriteFile(rawTxPath, rawTxContent); err != nil { return nil, fmt.Errorf("failed to write raw tx file: %v", err) } - defer io.DeleteFile(rawTxPath) + defer func() { + if err := io.DeleteFile(rawTxPath); err != nil { + fmt.Printf("failed to delete raw tx file: %v", err) + } + }() signCmd := exec.Command(state.binaryPath, "tx", "sign", rawTxPath, "--from", common.WeaveGasStationKeyName, "--node", state.l1RPC, "--chain-id", state.l1ChainId, "--keyring-backend", "test", "--output-document", rawTxPath) diff --git a/models/relayer/init.go b/models/relayer/init.go index 592b1274..9ab6a87b 100644 --- a/models/relayer/init.go +++ b/models/relayer/init.go @@ -528,7 +528,7 @@ func (m *KeysMnemonicDisplayInput) View() string { if state.l2KeyMethod == string(L2GenerateKey) { mnemonicText += styles.RenderMnemonic( - styles.RenderPrompt(fmt.Sprintf("Weave Relayer on L2"), []string{"L2"}, styles.Empty), + styles.RenderPrompt("Weave Relayer on L2", []string{"L2"}, styles.Empty), state.l2RelayerAddress, state.l2RelayerMnemonic, ) @@ -780,7 +780,7 @@ func NewFundingAmountSelect(ctx context.Context) *FundingAmountSelect { CannotBack: true, }, BaseModel: weavecontext.BaseModel{Ctx: ctx, CannotBack: true}, - question: fmt.Sprintf("Please select the filling amount option"), + question: "Please select the filling amount option", } } diff --git a/service/launchd.go b/service/launchd.go index d0d2f5f6..746b40b2 100644 --- a/service/launchd.go +++ b/service/launchd.go @@ -65,17 +65,17 @@ func (j *Launchd) Create(binaryVersion, appHome string) error { return j.reloadService() } -func (j *Launchd) unloadService() error { - userHome, err := os.UserHomeDir() - if err != nil { - return fmt.Errorf("failed to get user home directory: %v", err) - } - unloadCmd := exec.Command("launchctl", "unload", filepath.Join(userHome, fmt.Sprintf("Library/LaunchAgents/%s.plist", j.GetServiceName()))) - if err = unloadCmd.Run(); err != nil { - return fmt.Errorf("failed to unload service: %v", err) - } - return nil -} +// func (j *Launchd) unloadService() error { +// userHome, err := os.UserHomeDir() +// if err != nil { +// return fmt.Errorf("failed to get user home directory: %v", err) +// } +// unloadCmd := exec.Command("launchctl", "unload", filepath.Join(userHome, fmt.Sprintf("Library/LaunchAgents/%s.plist", j.GetServiceName()))) +// if err = unloadCmd.Run(); err != nil { +// return fmt.Errorf("failed to unload service: %v", err) +// } +// return nil +// } func (j *Launchd) reloadService() error { userHome, err := os.UserHomeDir() diff --git a/tests/integration/alias.go b/tests/integration/alias.go index 4c7ff74c..a3ce2c19 100644 --- a/tests/integration/alias.go +++ b/tests/integration/alias.go @@ -7,23 +7,23 @@ import ( ) var ( - pressEnter = InputStep{Msg: tea.KeyMsg{Type: tea.KeyEnter}} - pressSpace = InputStep{Msg: tea.KeyMsg{Type: tea.KeySpace}} - pressTab = InputStep{Msg: tea.KeyMsg{Type: tea.KeyTab}} - pressUp = InputStep{Msg: tea.KeyMsg{Type: tea.KeyUp}} - pressDown = InputStep{Msg: tea.KeyMsg{Type: tea.KeyDown}} + PressEnter = InputStep{Msg: tea.KeyMsg{Type: tea.KeyEnter}} + PressSpace = InputStep{Msg: tea.KeyMsg{Type: tea.KeySpace}} + PressTab = InputStep{Msg: tea.KeyMsg{Type: tea.KeyTab}} + PressUp = InputStep{Msg: tea.KeyMsg{Type: tea.KeyUp}} + PressDown = InputStep{Msg: tea.KeyMsg{Type: tea.KeyDown}} - waitFetching = WaitStep{Check: func() bool { + WaitFetching = WaitStep{Check: func() bool { time.Sleep(5 * time.Second) return true }} ) -func typeText(text string) InputStep { +func TypeText(text string) InputStep { return InputStep{Msg: tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune(text)}} } // waitFor receives waitCondition as a parameter, which should return true if the wait should be over. -func waitFor(waitCondition func() bool) WaitStep { +func WaitFor(waitCondition func() bool) WaitStep { return WaitStep{Check: waitCondition} } diff --git a/tests/integration/gas_station_test.go b/tests/integration/gas_station_test.go deleted file mode 100644 index 646b9898..00000000 --- a/tests/integration/gas_station_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package integration - -import ( - "os" - "path/filepath" - "testing" - - tea "github.com/charmbracelet/bubbletea" - "github.com/stretchr/testify/assert" - - "github.com/initia-labs/weave/common" - "github.com/initia-labs/weave/config" - "github.com/initia-labs/weave/context" - "github.com/initia-labs/weave/models" -) - -const ( - TestMnemonic string = "imitate sick vibrant bonus weather spice pave announce direct impulse strategy math" -) - -func setupGasStation(t *testing.T) tea.Model { - err := config.InitializeConfig() - assert.Nil(t, err) - - ctx := context.NewAppContext(models.NewExistingCheckerState()) - firstModel := models.NewGasStationMnemonicInput(ctx) - - steps := []Step{ - typeText(TestMnemonic), - pressEnter, - } - - return runProgramWithSteps(t, firstModel, steps) -} - -func TestGasStationSetup(t *testing.T) { - finalModel := setupGasStation(t) - - // Check the final state here - assert.IsType(t, &models.WeaveAppSuccessfullyInitialized{}, finalModel) - - if _, ok := finalModel.(*models.WeaveAppSuccessfullyInitialized); ok { - assert.True(t, ok) - } - - // Check if Weave home has been created - userHome, _ := os.UserHomeDir() - weaveDir := filepath.Join(userHome, common.WeaveDirectory) - _, err := os.Stat(weaveDir) - assert.Nil(t, err) - - // Assert values - weaveConfig := filepath.Join(weaveDir, "config.json") - compareJsonValue(t, weaveConfig, "common.gas_station_mnemonic", TestMnemonic) -} diff --git a/tests/integration/gas_station_test/gas_station_test.go b/tests/integration/gas_station_test/gas_station_test.go new file mode 100644 index 00000000..4aaab7dd --- /dev/null +++ b/tests/integration/gas_station_test/gas_station_test.go @@ -0,0 +1,34 @@ +package gas_station_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/initia-labs/weave/common" + "github.com/initia-labs/weave/models" + "github.com/initia-labs/weave/tests/integration" +) + +func TestGasStationSetup(t *testing.T) { + finalModel := integration.SetupGasStation(t) + + // Check the final state here + assert.IsType(t, &models.WeaveAppSuccessfullyInitialized{}, finalModel) + + if _, ok := finalModel.(*models.WeaveAppSuccessfullyInitialized); ok { + assert.True(t, ok) + } + + // Check if Weave home has been created + userHome, _ := os.UserHomeDir() + weaveDir := filepath.Join(userHome, common.WeaveDirectory) + _, err := os.Stat(weaveDir) + assert.Nil(t, err) + + // Assert values + weaveConfig := filepath.Join(weaveDir, "config.json") + integration.CompareJsonValue(t, weaveConfig, "common.gas_station_mnemonic", integration.GasStationMnemonic) +} diff --git a/tests/integration/initia_test.go b/tests/integration/initia_test.go deleted file mode 100644 index fc53d178..00000000 --- a/tests/integration/initia_test.go +++ /dev/null @@ -1,370 +0,0 @@ -package integration - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/initia-labs/weave/context" - "github.com/initia-labs/weave/models/initia" -) - -const ( - TestInitiaHome = ".initia.weave.test" -) - -func TestInitiaInitTestnetNoSync(t *testing.T) { - ctx := context.NewAppContext(initia.NewRunL1NodeState()) - ctx = context.SetInitiaHome(ctx, TestInitiaHome) - - firstModel := initia.NewRunL1NodeNetworkSelect(ctx) - - // Ensure that there is no previous Initia home - _, err := os.Stat(TestInitiaHome) - assert.NotNil(t, err) - - steps := []Step{ - pressEnter, - typeText("Moniker"), - pressEnter, - pressSpace, - pressEnter, - typeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), - pressEnter, - typeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), - pressEnter, - waitFor(func() bool { - if _, err := os.Stat(TestInitiaHome); os.IsNotExist(err) { - return false - } - return true - }), - pressDown, - pressDown, - pressEnter, - } - - finalModel := runProgramWithSteps(t, firstModel, steps) - defer clearTestDir(TestInitiaHome) - - // Check the final state here - assert.IsType(t, &initia.TerminalState{}, finalModel) - - if _, ok := finalModel.(*initia.TerminalState); ok { - assert.True(t, ok) - } - - // Check if Initia home has been created - _, err = os.Stat(TestInitiaHome) - assert.Nil(t, err) - - configTomlPath := filepath.Join(TestInitiaHome, "config/config.toml") - appTomlPath := filepath.Join(TestInitiaHome, "config/app.toml") - - if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { - t.Fatalf("Config toml file does not exist: %s", configTomlPath) - } - - if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { - t.Fatalf("App toml file does not exist: %s", appTomlPath) - } - - // Assert values - compareTomlValue(t, configTomlPath, "moniker", "Moniker") - compareTomlValue(t, configTomlPath, "p2p.seeds", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656") - compareTomlValue(t, configTomlPath, "p2p.persistent_peers", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656") - compareTomlValue(t, configTomlPath, "statesync.enable", false) - - compareTomlValue(t, appTomlPath, "minimum-gas-prices", "0.15uinit") - compareTomlValue(t, appTomlPath, "api.enable", "true") -} - -func TestInitiaInitTestnetStatesync(t *testing.T) { - ctx := context.NewAppContext(initia.NewRunL1NodeState()) - ctx = context.SetInitiaHome(ctx, TestInitiaHome) - - firstModel := initia.NewRunL1NodeNetworkSelect(ctx) - - // Ensure that there is no previous Initia home - _, err := os.Stat(TestInitiaHome) - assert.NotNil(t, err) - - steps := []Step{ - pressEnter, - typeText("Moniker"), - pressEnter, - pressSpace, - pressEnter, - typeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), - pressEnter, - typeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), - pressEnter, - waitFor(func() bool { - if _, err := os.Stat(TestInitiaHome); os.IsNotExist(err) { - return false - } - return true - }), - pressDown, - pressEnter, - waitFetching, - pressEnter, - typeText("https://initia-testnet-rpc.polkachu.com:443"), - pressEnter, - waitFetching, - typeText("1d9b9512f925cf8808e7f76d71a788d82089fe76@65.108.198.118:25756"), - pressEnter, - waitFetching, - } - - finalModel := runProgramWithSteps(t, firstModel, steps) - defer clearTestDir(TestInitiaHome) - - // Check the final state here - assert.IsType(t, &initia.TerminalState{}, finalModel) - - if _, ok := finalModel.(*initia.TerminalState); ok { - assert.True(t, ok) - } - - // Check if Initia home has been created - _, err = os.Stat(TestInitiaHome) - assert.Nil(t, err) - - configTomlPath := filepath.Join(TestInitiaHome, "config/config.toml") - appTomlPath := filepath.Join(TestInitiaHome, "config/app.toml") - - if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { - t.Fatalf("Config toml file does not exist: %s", configTomlPath) - } - - if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { - t.Fatalf("App toml file does not exist: %s", appTomlPath) - } - - // Assert values - compareTomlValue(t, configTomlPath, "moniker", "Moniker") - compareTomlValue(t, configTomlPath, "p2p.seeds", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656") - compareTomlValue(t, configTomlPath, "p2p.persistent_peers", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656,1d9b9512f925cf8808e7f76d71a788d82089fe76@65.108.198.118:25756") - compareTomlValue(t, configTomlPath, "statesync.enable", "true") - compareTomlValue(t, configTomlPath, "statesync.rpc_servers", "https://initia-testnet-rpc.polkachu.com:443,https://initia-testnet-rpc.polkachu.com:443") - - compareTomlValue(t, appTomlPath, "minimum-gas-prices", "0.15uinit") - compareTomlValue(t, appTomlPath, "api.enable", "true") -} - -func TestInitiaInitLocal(t *testing.T) { - ctx := context.NewAppContext(initia.NewRunL1NodeState()) - ctx = context.SetInitiaHome(ctx, TestInitiaHome) - - firstModel := initia.NewRunL1NodeNetworkSelect(ctx) - - // Ensure that there is no previous Initia home - _, err := os.Stat(TestInitiaHome) - assert.NotNil(t, err) - - steps := []Step{ - pressDown, - pressEnter, - waitFetching, - pressEnter, - typeText("ChainId-1"), - pressEnter, - typeText("Moniker"), - pressEnter, - typeText("0uinit"), - pressEnter, - pressEnter, - pressEnter, - pressEnter, - waitFor(func() bool { - if _, err := os.Stat(TestInitiaHome); os.IsNotExist(err) { - return false - } - return true - }), - } - - finalModel := runProgramWithSteps(t, firstModel, steps) - defer clearTestDir(TestInitiaHome) - - // Check the final state here - assert.IsType(t, &initia.InitializingAppLoading{}, finalModel) - - if _, ok := finalModel.(*initia.InitializingAppLoading); ok { - assert.True(t, ok) - } - - // Check if Initia home has been created - _, err = os.Stat(TestInitiaHome) - assert.Nil(t, err) - - configTomlPath := filepath.Join(TestInitiaHome, "config/config.toml") - appTomlPath := filepath.Join(TestInitiaHome, "config/app.toml") - - if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { - t.Fatalf("Config toml file does not exist: %s", configTomlPath) - } - - if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { - t.Fatalf("App toml file does not exist: %s", appTomlPath) - } - - // Assert values - compareTomlValue(t, configTomlPath, "moniker", "Moniker") - compareTomlValue(t, configTomlPath, "p2p.seeds", "") - compareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") - compareTomlValue(t, configTomlPath, "statesync.enable", false) - compareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") - - compareTomlValue(t, appTomlPath, "minimum-gas-prices", "0uinit") - compareTomlValue(t, appTomlPath, "api.enable", "false") -} - -func TestInitiaInitLocalExisting(t *testing.T) { - ctx := context.NewAppContext(initia.NewRunL1NodeState()) - ctx = context.SetInitiaHome(ctx, TestInitiaHome) - - firstModel := initia.NewRunL1NodeNetworkSelect(ctx) - - // Ensure that there is no previous Initia home - _, err := os.Stat(TestInitiaHome) - assert.NotNil(t, err) - - steps := []Step{ - pressDown, - pressEnter, - waitFetching, - pressEnter, - typeText("ChainId-1"), - pressEnter, - typeText("Moniker"), - pressEnter, - typeText("0uinit"), - pressEnter, - pressEnter, - pressEnter, - pressEnter, - waitFor(func() bool { - if _, err := os.Stat(TestInitiaHome); os.IsNotExist(err) { - return false - } - return true - }), - } - - finalModel := runProgramWithSteps(t, firstModel, steps) - - // Check the final state here - assert.IsType(t, &initia.InitializingAppLoading{}, finalModel) - - if _, ok := finalModel.(*initia.InitializingAppLoading); ok { - assert.True(t, ok) - } - - // Check if Initia home has been created - _, err = os.Stat(TestInitiaHome) - assert.Nil(t, err) - - configTomlPath := filepath.Join(TestInitiaHome, "config/config.toml") - appTomlPath := filepath.Join(TestInitiaHome, "config/app.toml") - - if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { - t.Fatalf("Config toml file does not exist: %s", configTomlPath) - } - - if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { - t.Fatalf("App toml file does not exist: %s", appTomlPath) - } - - // Assert values - compareTomlValue(t, configTomlPath, "moniker", "Moniker") - compareTomlValue(t, configTomlPath, "p2p.seeds", "") - compareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") - compareTomlValue(t, configTomlPath, "statesync.enable", false) - compareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") - - compareTomlValue(t, appTomlPath, "minimum-gas-prices", "0uinit") - compareTomlValue(t, appTomlPath, "api.enable", "false") - - ctx = context.NewAppContext(initia.NewRunL1NodeState()) - ctx = context.SetInitiaHome(ctx, TestInitiaHome) - - firstModel = initia.NewRunL1NodeNetworkSelect(ctx) - - // Ensure that there is an existing Initia home - _, err = os.Stat(TestInitiaHome) - assert.Nil(t, err) - - steps = []Step{ - pressDown, - pressEnter, - waitFetching, - pressEnter, - typeText("ChainId-2"), - pressEnter, - waitFetching, - pressEnter, - waitFetching, - pressEnter, - } - - finalModel = runProgramWithSteps(t, firstModel, steps) - - compareTomlValue(t, configTomlPath, "moniker", "Moniker") - compareTomlValue(t, configTomlPath, "p2p.seeds", "") - compareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") - compareTomlValue(t, configTomlPath, "statesync.enable", false) - compareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") - - compareTomlValue(t, appTomlPath, "minimum-gas-prices", "0uinit") - compareTomlValue(t, appTomlPath, "api.enable", "false") - - ctx = context.NewAppContext(initia.NewRunL1NodeState()) - ctx = context.SetInitiaHome(ctx, TestInitiaHome) - - firstModel = initia.NewRunL1NodeNetworkSelect(ctx) - - // Ensure that there is an existing Initia home - _, err = os.Stat(TestInitiaHome) - assert.Nil(t, err) - - steps = []Step{ - pressDown, - pressEnter, - waitFetching, - pressEnter, - typeText("ChainId-3"), - pressEnter, - waitFetching, - pressUp, - pressEnter, - typeText("NewMoniker"), - pressEnter, - typeText("0.015uinit"), - pressEnter, - pressSpace, - pressDown, - pressSpace, - pressEnter, - pressEnter, - pressEnter, - waitFetching, - pressUp, - pressEnter, - } - - finalModel = runProgramWithSteps(t, firstModel, steps) - defer clearTestDir(TestInitiaHome) - - compareTomlValue(t, configTomlPath, "moniker", "NewMoniker") - compareTomlValue(t, configTomlPath, "p2p.seeds", "") - compareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") - compareTomlValue(t, configTomlPath, "statesync.enable", false) - compareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") - - compareTomlValue(t, appTomlPath, "minimum-gas-prices", "0.015uinit") - compareTomlValue(t, appTomlPath, "api.enable", "true") -} diff --git a/tests/integration/initia_test/initia_test.go b/tests/integration/initia_test/initia_test.go new file mode 100644 index 00000000..a9085940 --- /dev/null +++ b/tests/integration/initia_test/initia_test.go @@ -0,0 +1,401 @@ +package initia_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/initia-labs/weave/context" + "github.com/initia-labs/weave/models/initia" + "github.com/initia-labs/weave/tests/integration" +) + +const ( + TestInitiaHome = ".initia.weave.test" +) + +func TestInitiaInitTestnetNoSync(t *testing.T) { + t.Parallel() + ctx := context.NewAppContext(initia.NewRunL1NodeState()) + initiaHome := TestInitiaHome + ".nosync" + ctx = context.SetInitiaHome(ctx, initiaHome) + + firstModel := initia.NewRunL1NodeNetworkSelect(ctx) + + // Ensure that there is no previous Initia home + _, err := os.Stat(initiaHome) + assert.NotNil(t, err) + + steps := integration.Steps{ + integration.PressEnter, + integration.TypeText("Moniker"), + integration.PressEnter, + integration.PressSpace, + integration.PressEnter, + integration.TypeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), + integration.PressEnter, + integration.TypeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), + integration.PressEnter, + integration.WaitFor(func() bool { + if _, err := os.Stat(initiaHome); os.IsNotExist(err) { + return false + } + return true + }), + integration.PressDown, + integration.PressDown, + integration.PressEnter, + } + + finalModel := integration.RunProgramWithSteps(t, firstModel, steps) + defer integration.ClearTestDir(initiaHome) + + // Check the final state here + assert.IsType(t, &initia.TerminalState{}, finalModel) + + if _, ok := finalModel.(*initia.TerminalState); ok { + assert.True(t, ok) + } + + // Check if Initia home has been created + _, err = os.Stat(initiaHome) + assert.Nil(t, err) + + configTomlPath := filepath.Join(initiaHome, "config/config.toml") + appTomlPath := filepath.Join(initiaHome, "config/app.toml") + + if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { + t.Fatalf("Config toml file does not exist: %s", configTomlPath) + } + + if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { + t.Fatalf("App toml file does not exist: %s", appTomlPath) + } + + // Assert values + integration.CompareTomlValue(t, configTomlPath, "moniker", "Moniker") + integration.CompareTomlValue(t, configTomlPath, "p2p.seeds", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656") + integration.CompareTomlValue(t, configTomlPath, "p2p.persistent_peers", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656") + integration.CompareTomlValue(t, configTomlPath, "statesync.enable", false) + + integration.CompareTomlValue(t, appTomlPath, "minimum-gas-prices", "0.15uinit") + integration.CompareTomlValue(t, appTomlPath, "api.enable", "true") +} + +func TestInitiaInitTestnetStatesync(t *testing.T) { + t.Parallel() + ctx := context.NewAppContext(initia.NewRunL1NodeState()) + initiaHome := TestInitiaHome + ".statesync" + ctx = context.SetInitiaHome(ctx, initiaHome) + + firstModel := initia.NewRunL1NodeNetworkSelect(ctx) + + // Ensure that there is no previous Initia home + _, err := os.Stat(initiaHome) + assert.NotNil(t, err) + + steps := integration.Steps{ + integration.PressEnter, + integration.TypeText("Moniker"), + integration.PressEnter, + integration.PressSpace, + integration.PressEnter, + integration.TypeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), + integration.PressEnter, + integration.TypeText("3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656"), + integration.PressEnter, + integration.WaitFor(func() bool { + if _, err := os.Stat(initiaHome); os.IsNotExist(err) { + return false + } + return true + }), + integration.PressDown, + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressEnter, + integration.TypeText("https://initia-testnet-rpc.polkachu.com:443"), + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.TypeText("1d9b9512f925cf8808e7f76d71a788d82089fe76@65.108.198.118:25756"), + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + } + + finalModel := integration.RunProgramWithSteps(t, firstModel, steps) + defer integration.ClearTestDir(initiaHome) + + // Check the final state here + assert.IsType(t, &initia.TerminalState{}, finalModel) + + if _, ok := finalModel.(*initia.TerminalState); ok { + assert.True(t, ok) + } + + // Check if Initia home has been created + _, err = os.Stat(initiaHome) + assert.Nil(t, err) + + configTomlPath := filepath.Join(initiaHome, "config/config.toml") + appTomlPath := filepath.Join(initiaHome, "config/app.toml") + + if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { + t.Fatalf("Config toml file does not exist: %s", configTomlPath) + } + + if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { + t.Fatalf("App toml file does not exist: %s", appTomlPath) + } + + // Assert values + integration.CompareTomlValue(t, configTomlPath, "moniker", "Moniker") + integration.CompareTomlValue(t, configTomlPath, "p2p.seeds", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656") + integration.CompareTomlValue(t, configTomlPath, "p2p.persistent_peers", "3715cdb41efb45714eb534c3943c5947f4894787@34.143.179.242:26656,1d9b9512f925cf8808e7f76d71a788d82089fe76@65.108.198.118:25756") + integration.CompareTomlValue(t, configTomlPath, "statesync.enable", "true") + integration.CompareTomlValue(t, configTomlPath, "statesync.rpc_servers", "https://initia-testnet-rpc.polkachu.com:443,https://initia-testnet-rpc.polkachu.com:443") + + integration.CompareTomlValue(t, appTomlPath, "minimum-gas-prices", "0.15uinit") + integration.CompareTomlValue(t, appTomlPath, "api.enable", "true") +} + +func TestInitiaInitLocal(t *testing.T) { + t.Parallel() + ctx := context.NewAppContext(initia.NewRunL1NodeState()) + initiaHome := TestInitiaHome + ".local" + ctx = context.SetInitiaHome(ctx, initiaHome) + + firstModel := initia.NewRunL1NodeNetworkSelect(ctx) + + // Ensure that there is no previous Initia home + _, err := os.Stat(initiaHome) + assert.NotNil(t, err) + + steps := []integration.Step{ + integration.PressDown, + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressEnter, + integration.TypeText("ChainId-1"), + integration.PressEnter, + integration.TypeText("Moniker"), + integration.PressEnter, + integration.TypeText("0uinit"), + integration.PressEnter, + integration.PressEnter, + integration.PressEnter, + integration.PressEnter, + integration.WaitFor(func() bool { + if _, err := os.Stat(initiaHome); os.IsNotExist(err) { + return false + } + return true + }), + } + + finalModel := integration.RunProgramWithSteps(t, firstModel, steps) + defer integration.ClearTestDir(initiaHome) + + // Check the final state here + assert.IsType(t, &initia.InitializingAppLoading{}, finalModel) + + if _, ok := finalModel.(*initia.InitializingAppLoading); ok { + assert.True(t, ok) + } + + // Check if Initia home has been created + _, err = os.Stat(initiaHome) + assert.Nil(t, err) + + configTomlPath := filepath.Join(initiaHome, "config/config.toml") + appTomlPath := filepath.Join(initiaHome, "config/app.toml") + + if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { + t.Fatalf("Config toml file does not exist: %s", configTomlPath) + } + + if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { + t.Fatalf("App toml file does not exist: %s", appTomlPath) + } + + // Assert values + integration.CompareTomlValue(t, configTomlPath, "moniker", "Moniker") + integration.CompareTomlValue(t, configTomlPath, "p2p.seeds", "") + integration.CompareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") + integration.CompareTomlValue(t, configTomlPath, "statesync.enable", false) + integration.CompareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") + + integration.CompareTomlValue(t, appTomlPath, "minimum-gas-prices", "0uinit") + integration.CompareTomlValue(t, appTomlPath, "api.enable", "false") +} + +func TestInitiaInitLocalExisting(t *testing.T) { + t.Parallel() + ctx := context.NewAppContext(initia.NewRunL1NodeState()) + initiaHome := TestInitiaHome + ".local.existing" + ctx = context.SetInitiaHome(ctx, initiaHome) + + firstModel := initia.NewRunL1NodeNetworkSelect(ctx) + + // Ensure that there is no previous Initia home + _, err := os.Stat(initiaHome) + assert.NotNil(t, err) + + steps := []integration.Step{ + integration.PressDown, + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressEnter, + integration.TypeText("ChainId-1"), + integration.PressEnter, + integration.TypeText("Moniker"), + integration.PressEnter, + integration.TypeText("0uinit"), + integration.PressEnter, + integration.PressEnter, + integration.PressEnter, + integration.PressEnter, + integration.WaitFor(func() bool { + if _, err := os.Stat(initiaHome); os.IsNotExist(err) { + return false + } + return true + }), + } + + finalModel := integration.RunProgramWithSteps(t, firstModel, steps) + + // Check the final state here + assert.IsType(t, &initia.InitializingAppLoading{}, finalModel) + + if _, ok := finalModel.(*initia.InitializingAppLoading); ok { + assert.True(t, ok) + } + + // Check if Initia home has been created + _, err = os.Stat(initiaHome) + assert.Nil(t, err) + + configTomlPath := filepath.Join(initiaHome, "config/config.toml") + appTomlPath := filepath.Join(initiaHome, "config/app.toml") + + if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { + t.Fatalf("Config toml file does not exist: %s", configTomlPath) + } + + if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { + t.Fatalf("App toml file does not exist: %s", appTomlPath) + } + + // Assert values + integration.CompareTomlValue(t, configTomlPath, "moniker", "Moniker") + integration.CompareTomlValue(t, configTomlPath, "p2p.seeds", "") + integration.CompareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") + integration.CompareTomlValue(t, configTomlPath, "statesync.enable", false) + integration.CompareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") + + integration.CompareTomlValue(t, appTomlPath, "minimum-gas-prices", "0uinit") + integration.CompareTomlValue(t, appTomlPath, "api.enable", "false") + + ctx = context.NewAppContext(initia.NewRunL1NodeState()) + ctx = context.SetInitiaHome(ctx, initiaHome) + + firstModel = initia.NewRunL1NodeNetworkSelect(ctx) + + // Ensure that there is an existing Initia home + _, err = os.Stat(initiaHome) + assert.Nil(t, err) + + steps = []integration.Step{ + integration.PressDown, + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressEnter, + integration.TypeText("ChainId-2"), + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressEnter, + } + + finalModel = integration.RunProgramWithSteps(t, firstModel, steps) + + integration.CompareTomlValue(t, configTomlPath, "moniker", "Moniker") + integration.CompareTomlValue(t, configTomlPath, "p2p.seeds", "") + integration.CompareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") + integration.CompareTomlValue(t, configTomlPath, "statesync.enable", false) + integration.CompareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") + + integration.CompareTomlValue(t, appTomlPath, "minimum-gas-prices", "0uinit") + integration.CompareTomlValue(t, appTomlPath, "api.enable", "false") + + ctx = context.NewAppContext(initia.NewRunL1NodeState()) + ctx = context.SetInitiaHome(ctx, initiaHome) + + firstModel = initia.NewRunL1NodeNetworkSelect(ctx) + + // Ensure that there is an existing Initia home + _, err = os.Stat(initiaHome) + assert.Nil(t, err) + + steps = integration.Steps{ + integration.PressDown, + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressEnter, + integration.TypeText("ChainId-3"), + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressUp, + integration.PressEnter, + integration.TypeText("NewMoniker"), + integration.PressEnter, + integration.TypeText("0.015uinit"), + integration.PressEnter, + integration.PressSpace, + integration.PressDown, + integration.PressSpace, + integration.PressEnter, + integration.PressEnter, + integration.PressEnter, + integration.WaitFor(func() bool { + return true + }), + integration.PressUp, + integration.PressEnter, + } + + finalModel = integration.RunProgramWithSteps(t, firstModel, steps) + defer integration.ClearTestDir(initiaHome) + + integration.CompareTomlValue(t, configTomlPath, "moniker", "NewMoniker") + integration.CompareTomlValue(t, configTomlPath, "p2p.seeds", "") + integration.CompareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") + integration.CompareTomlValue(t, configTomlPath, "statesync.enable", false) + integration.CompareTomlValue(t, configTomlPath, "statesync.rpc_servers", "") + + integration.CompareTomlValue(t, appTomlPath, "minimum-gas-prices", "0.015uinit") + integration.CompareTomlValue(t, appTomlPath, "api.enable", "true") +} diff --git a/tests/integration/minitia_test.go b/tests/integration/minitia_test.go deleted file mode 100644 index 1f9641f2..00000000 --- a/tests/integration/minitia_test.go +++ /dev/null @@ -1,183 +0,0 @@ -package integration - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/initia-labs/weave/context" - "github.com/initia-labs/weave/models/minitia" -) - -const ( - TestMinitiaHome = ".minitia.weave.test" -) - -func TestMinitiaLaunchWithExisting(t *testing.T) { - _ = setupGasStation(t) - - ctx := context.NewAppContext(*minitia.NewLaunchState()) - ctx = context.SetMinitiaHome(ctx, TestMinitiaHome) - - firstModel := minitia.NewExistingMinitiaChecker(ctx) - - // Ensure that there is no previous Minitia home - _, err := os.Stat(TestMinitiaHome) - assert.NotNil(t, err) - - steps := []Step{ - waitFetching, - pressEnter, - pressEnter, - waitFetching, - pressEnter, - typeText("rollup-1"), - pressEnter, - pressTab, - pressEnter, - pressTab, - pressEnter, - pressTab, - pressEnter, - pressTab, - pressEnter, - pressDown, - pressEnter, - pressEnter, - pressEnter, - waitFetching, - pressDown, - pressEnter, - typeText("1234567"), - pressEnter, - typeText("1000000"), - pressEnter, - typeText("1111111"), - pressEnter, - typeText("234567"), - pressEnter, - typeText("123456789123456789"), - pressEnter, - typeText("123456789123456789"), - pressEnter, - pressDown, - pressEnter, - waitFetching, - waitFetching, - typeText("continue"), - pressEnter, - typeText("y"), - pressEnter, - } - - finalModel := runProgramWithSteps(t, firstModel, steps) - - // Check the final state here - assert.IsType(t, &minitia.TerminalState{}, finalModel) - - if _, ok := finalModel.(*minitia.TerminalState); ok { - assert.True(t, ok) - } - - // Check if Initia home has been created - _, err = os.Stat(TestMinitiaHome) - assert.Nil(t, err) - - configTomlPath := filepath.Join(TestMinitiaHome, "config/config.toml") - appTomlPath := filepath.Join(TestMinitiaHome, "config/app.toml") - - if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { - t.Fatalf("Config toml file does not exist: %s", configTomlPath) - } - - if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { - t.Fatalf("App toml file does not exist: %s", appTomlPath) - } - - // Assert values - compareTomlValue(t, configTomlPath, "p2p.seeds", "") - compareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") - compareTomlValue(t, configTomlPath, "statesync.enable", false) - - compareTomlValue(t, appTomlPath, "minimum-gas-prices", "0umin") - compareTomlValue(t, appTomlPath, "api.enable", true) - - artifactsConfigPath := filepath.Join(TestMinitiaHome, "artifacts/config.json") - - if _, err := os.Stat(artifactsConfigPath); os.IsNotExist(err) { - t.Fatalf("Artifacts config json file does not exist: %s", artifactsConfigPath) - } - - compareJsonValue(t, artifactsConfigPath, "l2_config.chain_id", "rollup-1") - compareJsonValue(t, artifactsConfigPath, "l2_config.denom", "umin") - compareJsonValue(t, artifactsConfigPath, "l2_config.moniker", "operator") - compareJsonValue(t, artifactsConfigPath, "op_bridge.enable_oracle", true) - - // Try again with existing Minitia home - ctx = context.NewAppContext(*minitia.NewLaunchState()) - ctx = context.SetMinitiaHome(ctx, TestMinitiaHome) - - firstModel = minitia.NewExistingMinitiaChecker(ctx) - - // Ensure that there is an existing Minitia home - _, err = os.Stat(TestMinitiaHome) - assert.Nil(t, err) - - steps = []Step{ - waitFetching, - typeText("delete"), - pressEnter, - pressEnter, - pressDown, - pressEnter, - waitFetching, - typeText("rollup-2"), - pressEnter, - typeText("uroll"), - pressEnter, - typeText("computer"), - pressEnter, - pressTab, - pressEnter, - pressTab, - pressEnter, - pressDown, - pressEnter, - pressEnter, - pressDown, - pressEnter, - typeText("lonely fly lend protect mix order legal organ fruit donkey dog state"), - pressEnter, - typeText("boy salmon resist afford dog cereal first myth require enough sunny cargo"), - pressEnter, - typeText("young diagram garment finish barrel output pledge borrow tonight frozen clerk sadness"), - pressEnter, - typeText("patrol search opera diary hidden giggle crisp together toy print lemon very"), - pressEnter, - typeText("door radar exhibit equip mom beach drift harbor tomorrow tree long stereo"), - pressEnter, - waitFetching, - pressEnter, - pressEnter, - typeText("init16pawh0v7w996jrmtzugz3hmhq0wx6ndq5pp0dr"), - pressEnter, - typeText("1234567890"), - pressEnter, - pressDown, - pressEnter, - waitFetching, - waitFetching, - typeText("y"), - pressEnter, - } - - finalModel = runProgramWithSteps(t, firstModel, steps) - defer clearTestDir(TestMinitiaHome) - - // Assert values - compareJsonValue(t, artifactsConfigPath, "l2_config.chain_id", "rollup-2") - compareJsonValue(t, artifactsConfigPath, "l2_config.denom", "uroll") - compareJsonValue(t, artifactsConfigPath, "l2_config.moniker", "computer") -} diff --git a/tests/integration/minitia_test/minitia_test.go b/tests/integration/minitia_test/minitia_test.go new file mode 100644 index 00000000..c81fe8cb --- /dev/null +++ b/tests/integration/minitia_test/minitia_test.go @@ -0,0 +1,185 @@ +package minitia_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/initia-labs/weave/context" + "github.com/initia-labs/weave/models/minitia" + "github.com/initia-labs/weave/tests/integration" +) + +const ( + TestMinitiaHome = ".minitia.weave.test" +) + +func TestMinitiaLaunchWithExisting(t *testing.T) { + t.Skip("Skipping minitia launch with existing test") + _ = integration.SetupGasStation(t) + + ctx := context.NewAppContext(*minitia.NewLaunchState()) + ctx = context.SetMinitiaHome(ctx, TestMinitiaHome) + + firstModel := minitia.NewExistingMinitiaChecker(ctx) + + // Ensure that there is no previous Minitia home + _, err := os.Stat(TestMinitiaHome) + assert.NotNil(t, err) + + steps := integration.Steps{ + integration.WaitFetching, + integration.PressEnter, + integration.PressEnter, + integration.WaitFetching, + integration.PressEnter, + integration.TypeText("rollup-1"), + integration.PressEnter, + integration.PressTab, + integration.PressEnter, + integration.PressTab, + integration.PressEnter, + integration.PressTab, + integration.PressEnter, + integration.PressTab, + integration.PressEnter, + integration.PressDown, + integration.PressEnter, + integration.PressEnter, + integration.PressEnter, + integration.WaitFetching, + integration.PressDown, + integration.PressEnter, + integration.TypeText("1234567"), + integration.PressEnter, + integration.TypeText("1000000"), + integration.PressEnter, + integration.TypeText("1111111"), + integration.PressEnter, + integration.TypeText("234567"), + integration.PressEnter, + integration.TypeText("123456789123456789"), + integration.PressEnter, + integration.TypeText("123456789123456789"), + integration.PressEnter, + integration.PressDown, + integration.PressEnter, + integration.WaitFetching, + integration.WaitFetching, + integration.TypeText("continue"), + integration.PressEnter, + integration.TypeText("y"), + integration.PressEnter, + } + + finalModel := integration.RunProgramWithSteps(t, firstModel, steps) + + // Check the final state here + assert.IsType(t, &minitia.TerminalState{}, finalModel) + + if _, ok := finalModel.(*minitia.TerminalState); ok { + assert.True(t, ok) + } + + // Check if Initia home has been created + _, err = os.Stat(TestMinitiaHome) + assert.Nil(t, err) + + configTomlPath := filepath.Join(TestMinitiaHome, "config/config.toml") + appTomlPath := filepath.Join(TestMinitiaHome, "config/app.toml") + + if _, err := os.Stat(configTomlPath); os.IsNotExist(err) { + t.Fatalf("Config toml file does not exist: %s", configTomlPath) + } + + if _, err := os.Stat(appTomlPath); os.IsNotExist(err) { + t.Fatalf("App toml file does not exist: %s", appTomlPath) + } + + // Assert values + integration.CompareTomlValue(t, configTomlPath, "p2p.seeds", "") + integration.CompareTomlValue(t, configTomlPath, "p2p.persistent_peers", "") + integration.CompareTomlValue(t, configTomlPath, "statesync.enable", false) + + integration.CompareTomlValue(t, appTomlPath, "minimum-gas-prices", "0umin") + integration.CompareTomlValue(t, appTomlPath, "api.enable", true) + + artifactsConfigPath := filepath.Join(TestMinitiaHome, "artifacts/config.json") + + if _, err := os.Stat(artifactsConfigPath); os.IsNotExist(err) { + t.Fatalf("Artifacts config json file does not exist: %s", artifactsConfigPath) + } + + integration.CompareJsonValue(t, artifactsConfigPath, "l2_config.chain_id", "rollup-1") + integration.CompareJsonValue(t, artifactsConfigPath, "l2_config.denom", "umin") + integration.CompareJsonValue(t, artifactsConfigPath, "l2_config.moniker", "operator") + integration.CompareJsonValue(t, artifactsConfigPath, "op_bridge.enable_oracle", true) + + // Try again with existing Minitia home + ctx = context.NewAppContext(*minitia.NewLaunchState()) + ctx = context.SetMinitiaHome(ctx, TestMinitiaHome) + + firstModel = minitia.NewExistingMinitiaChecker(ctx) + + // Ensure that there is an existing Minitia home + _, err = os.Stat(TestMinitiaHome) + assert.Nil(t, err) + + steps = integration.Steps{ + integration.WaitFetching, + integration.TypeText("delete"), + integration.PressEnter, + integration.PressEnter, + integration.PressDown, + integration.PressEnter, + integration.WaitFetching, + integration.TypeText("rollup-2"), + integration.PressEnter, + integration.TypeText("uroll"), + integration.PressEnter, + integration.TypeText("computer"), + integration.PressEnter, + integration.PressTab, + integration.PressEnter, + integration.PressTab, + integration.PressEnter, + integration.PressDown, + integration.PressEnter, + integration.PressEnter, + integration.PressDown, + integration.PressEnter, + integration.TypeText("lonely fly lend protect mix order legal organ fruit donkey dog state"), + integration.PressEnter, + integration.TypeText("boy salmon resist afford dog cereal first myth require enough sunny cargo"), + integration.PressEnter, + integration.TypeText("young diagram garment finish barrel output pledge borrow tonight frozen clerk sadness"), + integration.PressEnter, + integration.TypeText("patrol search opera diary hidden giggle crisp together toy print lemon very"), + integration.PressEnter, + integration.TypeText("door radar exhibit equip mom beach drift harbor tomorrow tree long stereo"), + integration.PressEnter, + integration.WaitFetching, + integration.PressEnter, + integration.PressEnter, + integration.TypeText("init16pawh0v7w996jrmtzugz3hmhq0wx6ndq5pp0dr"), + integration.PressEnter, + integration.TypeText("1234567890"), + integration.PressEnter, + integration.PressDown, + integration.PressEnter, + integration.WaitFetching, + integration.WaitFetching, + integration.TypeText("y"), + integration.PressEnter, + } + + finalModel = integration.RunProgramWithSteps(t, firstModel, steps) + defer integration.ClearTestDir(TestMinitiaHome) + + // Assert values + integration.CompareJsonValue(t, artifactsConfigPath, "l2_config.chain_id", "rollup-2") + integration.CompareJsonValue(t, artifactsConfigPath, "l2_config.denom", "uroll") + integration.CompareJsonValue(t, artifactsConfigPath, "l2_config.moniker", "computer") +} diff --git a/tests/integration/opinit_test.go b/tests/integration/opinit_test/opinit_test.go similarity index 99% rename from tests/integration/opinit_test.go rename to tests/integration/opinit_test/opinit_test.go index 5d765deb..86c5eab1 100644 --- a/tests/integration/opinit_test.go +++ b/tests/integration/opinit_test/opinit_test.go @@ -1,4 +1,4 @@ -package integration +package opinit_test const ( TestOPInitHome = ".opinit.weave.test" diff --git a/tests/integration/testutil.go b/tests/integration/testutil.go index 3bdd3ae2..027ad173 100644 --- a/tests/integration/testutil.go +++ b/tests/integration/testutil.go @@ -8,6 +8,10 @@ import ( "testing" "time" + "github.com/initia-labs/weave/config" + "github.com/initia-labs/weave/context" + "github.com/initia-labs/weave/models" + tea "github.com/charmbracelet/bubbletea" "github.com/pelletier/go-toml/v2" "github.com/stretchr/testify/assert" @@ -16,6 +20,7 @@ import ( const ( DefaultMaxWaitRetry = 300 DefaultPostWaitPeriod = 5 * time.Second + GasStationMnemonic = "imitate sick vibrant bonus weather spice pave announce direct impulse strategy math" ) type Step interface { @@ -47,7 +52,7 @@ func (w WaitStep) Wait() bool { return w.Check() } -func runProgramWithSteps(t *testing.T, program tea.Model, steps Steps) tea.Model { +func RunProgramWithSteps(t *testing.T, program tea.Model, steps Steps) tea.Model { prog := tea.NewProgram(program, tea.WithInput(nil)) done := make(chan struct{}) finalModel := tea.Model(nil) @@ -89,13 +94,13 @@ func runProgramWithSteps(t *testing.T, program tea.Model, steps Steps) tea.Model return finalModel } -func clearTestDir(dir string) { +func ClearTestDir(dir string) { if err := os.RemoveAll(dir); err != nil { panic(fmt.Sprintf("failed to remove test directory: %v", err)) } } -func getTomlValue(filePath, key string) (interface{}, error) { +func GetTomlValue(filePath, key string) (interface{}, error) { data, err := os.ReadFile(filePath) if err != nil { return nil, err @@ -124,14 +129,14 @@ func getTomlValue(filePath, key string) (interface{}, error) { return nil, nil } -func compareTomlValue(t *testing.T, filePath, key string, expectedValue interface{}) { - value, err := getTomlValue(filePath, key) +func CompareTomlValue(t *testing.T, filePath, key string, expectedValue interface{}) { + value, err := GetTomlValue(filePath, key) assert.NoError(t, err, "Error loading TOML file or traversing key") assert.Equal(t, expectedValue, value, "Mismatch for key %s", key) } -func getJsonValue(filePath, key string) (interface{}, error) { +func GetJsonValue(filePath, key string) (interface{}, error) { data, err := os.ReadFile(filePath) if err != nil { return nil, err @@ -160,9 +165,24 @@ func getJsonValue(filePath, key string) (interface{}, error) { return nil, nil } -func compareJsonValue(t *testing.T, filePath, key string, expectedValue interface{}) { - value, err := getJsonValue(filePath, key) +func CompareJsonValue(t *testing.T, filePath, key string, expectedValue interface{}) { + value, err := GetJsonValue(filePath, key) assert.NoError(t, err, "Error loading JSON file or traversing key") assert.Equal(t, expectedValue, value, "Mismatch for key %s", key) } + +func SetupGasStation(t *testing.T) tea.Model { + err := config.InitializeConfig() + assert.Nil(t, err) + + ctx := context.NewAppContext(models.NewExistingCheckerState()) + firstModel := models.NewGasStationMnemonicInput(ctx) + + steps := Steps{ + TypeText(GasStationMnemonic), + PressEnter, + } + + return RunProgramWithSteps(t, firstModel, steps) +}