From 545da99e75145c1efb7300d81e394c88f1a51f7b Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Thu, 22 Aug 2024 10:30:33 +0000 Subject: [PATCH] Initial Commit --- .github/workflows/ci.yml | 35 ++++++++++ .gitignore | 2 + LICENSE | 19 +++++ README.md | 5 ++ go.mod | 5 ++ go.sum | 2 + main.go | 81 +++++++++++++++++++++ main_test.go | 147 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 296 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 main_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..43f80c9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,35 @@ +name: ci +on: + push: + branches: + - main +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup FluentCI + uses: fluentci-io/setup-fluentci@v5 + with: + wasm: true + plugin: pkgx + args: install go + env: + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: go get & build + run: | + go get + go build -o ./bin/main + - name: Check code style + run: gofmt main.go | diff --ignore-tab-expansion main.go - + - name: go test + run: | + fluentci run --wasm postgres start + pkgx psql --host=localhost -d postgres -U `whoami` -c 'CREATE DATABASE s2;' + pkgx psql --host=localhost -d postgres -U `whoami` -c 'CREATE USER postgres CREATEROLE;' + pkgx psql --host=localhost -d postgres -U `whoami` -c 'GRANT ALL PRIVILEGES ON DATABASE s2 TO postgres;' + go install gotest.tools/gotestsum@latest + gotestsum --junitfile junit.xml ./... + - name: Test web server + run: | + curl --silent localhost:8001/time | grep "The current time is" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..692c2fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +bin \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..515dd5f --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2024 Tsiry Sandratraina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..35a5a6d --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# FluentCI demo for Go + +[![ci](https://github.com/fluentci-demos/fluentci-demo-go/actions/workflows/ci.yml/badge.svg)](https://github.com/fluentci-demos/fluentci-demo-go/actions/workflows/ci.yml) + +This is an example application and CI pipeline showing how to build and test Go project with FluentCI. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7f799cf --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/fluentci-demos/fluentci-demo-go + +go 1.21 + +require github.com/lib/pq v1.10.9 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..aeddeae --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= diff --git a/main.go b/main.go new file mode 100644 index 0000000..8b370f9 --- /dev/null +++ b/main.go @@ -0,0 +1,81 @@ +package main + +import ( + "database/sql" + "fmt" + "net/http" + "os" + "time" + + _ "github.com/lib/pq" +) + +func myHandler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) + fmt.Printf("Served: %s\n", r.Host) +} + +func timeHandler(w http.ResponseWriter, r *http.Request) { + t := time.Now().Format(time.RFC1123) + Body := "The current time is:" + fmt.Fprintf(w, "

%s

", Body) + fmt.Fprintf(w, "

%s

\n", t) + fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) + fmt.Printf("Served time for: %s\n", r.Host) +} + +func getData(w http.ResponseWriter, r *http.Request) { + fmt.Printf("Serving: %s\n", r.URL.Path) + fmt.Printf("Served: %s\n", r.Host) + + connStr := "user=postgres dbname=s2 sslmode=disable" + db, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Fprintf(w, "

%s

", err) + return + } + + rows, err := db.Query("SELECT * FROM users") + if err != nil { + fmt.Fprintf(w, "

%s

\n", err) + return + } + defer rows.Close() + + for rows.Next() { + var id int + var firstName string + var lastName string + err = rows.Scan(&id, &firstName, &lastName) + if err != nil { + fmt.Fprintf(w, "

%s

\n", err) + return + } + fmt.Fprintf(w, "

%d, %s, %s

\n", id, firstName, lastName) + } + + err = rows.Err() + if err != nil { + fmt.Fprintf(w, "

%s

", err) + return + } +} + +func main() { + PORT := ":8001" + arguments := os.Args + if len(arguments) != 1 { + PORT = ":" + arguments[1] + } + fmt.Println("Using port number: ", PORT) + + http.HandleFunc("/time", timeHandler) + http.HandleFunc("/getdata", getData) + http.HandleFunc("/", myHandler) + + err := http.ListenAndServe(PORT, nil) + if err != nil { + fmt.Println(err) + return + } +} diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..a2adcef --- /dev/null +++ b/main_test.go @@ -0,0 +1,147 @@ +package main + +import ( + "database/sql" + "fmt" + "net/http" + "net/http/httptest" + "testing" +) + +func createTable() { + connStr := "user=postgres dbname=s2 sslmode=disable" + db, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + } + + const query = ` + CREATE TABLE IF NOT EXISTS users ( + id SERIAL PRIMARY KEY, + first_name TEXT, + last_name TEXT + )` + + _, err = db.Exec(query) + if err != nil { + fmt.Println(err) + return + } + db.Close() +} + +func dropTable() { + connStr := "user=postgres dbname=s2 sslmode=disable" + db, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + return + } + + _, err = db.Exec("DROP TABLE IF EXISTS users") + if err != nil { + fmt.Println(err) + return + } + db.Close() +} + +func insertRecord(query string) { + connStr := "user=postgres dbname=s2 sslmode=disable" + db, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + return + } + _, err = db.Exec(query) + if err != nil { + fmt.Println(err) + return + } + db.Close() +} + +func Test_count(t *testing.T) { + var count int + createTable() + + insertRecord("INSERT INTO users (first_name, last_name) VALUES ('John', 'Doe')") + insertRecord("INSERT INTO users (first_name, last_name) VALUES ('Mihalis', 'Tsoukalos')") + insertRecord("INSERT INTO users (first_name, last_name) VALUES ('Marko', 'Anastasov')") + + connStr := "user=postgres dbname=s2 sslmode=disable" + db, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + return + } + + row := db.QueryRow("SELECT COUNT(*) FROM users") + err = row.Scan(&count) + db.Close() + + if count != 3 { + t.Errorf("Select query returned %d", count) + } + dropTable() +} + +func Test_queryDB(t *testing.T) { + createTable() + + connStr := "user=postgres dbname=s2 sslmode=disable" + db, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + return + } + + query := "INSERT INTO users (first_name, last_name) VALUES ('Random Text', '123456')" + insertRecord(query) + + rows, err := db.Query(`SELECT * FROM users WHERE last_name=$1`, `123456`) + if err != nil { + fmt.Println(err) + return + } + var col1 int + var col2 string + var col3 string + for rows.Next() { + rows.Scan(&col1, &col2, &col3) + } + if col2 != "Random Text" { + t.Errorf("first_name returned %s", col2) + } + + if col3 != "123456" { + t.Errorf("last_name returned %s", col3) + } + + db.Close() + dropTable() +} + +func Test_record(t *testing.T) { + createTable() + insertRecord("INSERT INTO users (first_name, last_name) VALUES ('John', 'Doe')") + + req, err := http.NewRequest("GET", "/getdata", nil) + if err != nil { + fmt.Println(err) + return + } + rr := httptest.NewRecorder() + handler := http.HandlerFunc(getData) + handler.ServeHTTP(rr, req) + + status := rr.Code + if status != http.StatusOK { + t.Errorf("Handler returned %v", status) + } + + if rr.Body.String() != "

1, John, Doe

\n" { + t.Errorf("Wrong server response!") + } + dropTable() +}