Best Go-testdeep code snippet using td.matchString
td-agent_exporter_test.go
Source:td-agent_exporter_test.go
1package main2import (3 "flag"4 "io/ioutil"5 "net/http"6 "regexp"7 "testing"8 "time"9 "github.com/prometheus/common/log"10)11// unit test12func TestParseArgDefaultValues(t *testing.T) {13 parseTargetArgs := []string{}14 flag.CommandLine.Parse(parseTargetArgs)15 if *listenAddress != "9256" {16 t.Errorf("listenAddress default value want %v but %v.", "9256", *listenAddress)17 }18 if *metricsPath != "/metrics" {19 t.Errorf("metricsPath default value want %v but %v.", "/metrics", *metricsPath)20 }21 if *processFileName != "ruby" {22 t.Errorf("processFileName default value want %v but %v.", "ruby", *processFileName)23 }24 if *processNamePrefix != "" {25 t.Errorf("processNamePrefix default value want %v but %v.", "", *processNamePrefix)26 }27}28func TestParseArgSpecifiedValues(t *testing.T) {29 parseTargetArgs := []string{"-web.listen-address", "19256", "-web.telemetry-path", "/metricsPath", "-fluentd.process_file_name", "td-agent", "-fluentd.process_name_prefix", "prefix"}30 flag.CommandLine.Parse(parseTargetArgs)31 if *listenAddress != "19256" {32 t.Errorf("listenAddress default value want %v but %v.", "19256", *listenAddress)33 }34 if *metricsPath != "/metricsPath" {35 t.Errorf("metricsPath default value want %v but %v.", "/metricsPath", *metricsPath)36 }37 if *processFileName != "td-agent" {38 t.Errorf("processFileName default value want %v but %v.", "td-agent", *processFileName)39 }40 if *processNamePrefix != "prefix" {41 t.Errorf("processNamePrefix default value want %v but %v.", "prefix", *processNamePrefix)42 }43}44func TestUnitFilterWithoutProcessNamePrefix(t *testing.T) {45 lines := []string{46 "UID PID PPID C STIME TTY TIME CMD",47 "root 1 0 0 03:43 pts/0 00:00:00 /bin/bash",48 "root 115 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid",49 "root 118 115 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid --under-supervisor",50 "root 125 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_1.log --daemon /var/run/td-agent/td-agent_1.pid --config /etc/td-agent/td-agent_1.conf",51 "root 128 125 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_1.log --daemon /var/run/td-agent/td-agent_1.pid --config /etc/td-agent/td-agent_1.conf --under-supervisor",52 "root 142 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_2.log --daemon /var/run/td-agent/td-agent_2.pid --config /etc/td-agent/td-agent_2.conf",53 "root 145 142 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_2.log --daemon /var/run/td-agent/td-agent_2.pid --config /etc/td-agent/td-agent_2.conf --under-supervisor",54 "root 152 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_3.log --daemon /var/run/td-agent/td-agent_3.pid --config /etc/td-agent/td-agent_3.conf",55 "root 155 152 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_3.log --daemon /var/run/td-agent/td-agent_3.pid --config /etc/td-agent/td-agent_3.conf --under-supervisor",56 "root 163 1 0 03:44 ? 00:00:00 supervisor:foo_a",57 "root 166 163 0 03:44 ? 00:00:01 worker:foo_a",58 "root 175 1 0 03:45 ? 00:00:00 supervisor:foo_b",59 "root 178 175 0 03:45 ? 00:00:01 worker:foo_b",60 "root 186 1 0 03:45 ? 00:00:00 supervisor:foo_c",61 "root 189 186 0 03:45 ? 00:00:01 worker:foo_c",62 "root 191 1 0 03:45 pts/0 00:00:01 worker:from_fluentd",63 "root 193 1 0 03:45 pts/0 00:00:01 worker:from_td_agent",64 }65 processName := ""66 processNamePrefix = &processName67 exporter := NewExporter()68 filtered := exporter.filter(lines)69 log.Info(filtered)70 if len(filtered) != 4 {71 t.Error("filtered array len doesn't match")72 }73}74func TestUnitFilterWithProcessNamePrefix(t *testing.T) {75 lines := []string{76 "UID PID PPID C STIME TTY TIME CMD",77 "root 1 0 0 03:43 pts/0 00:00:00 /bin/bash",78 "root 115 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid",79 "root 118 115 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid --under-supervisor",80 "root 125 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_1.log --daemon /var/run/td-agent/td-agent_1.pid --config /etc/td-agent/td-agent_1.conf",81 "root 128 125 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_1.log --daemon /var/run/td-agent/td-agent_1.pid --config /etc/td-agent/td-agent_1.conf --under-supervisor",82 "root 142 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_2.log --daemon /var/run/td-agent/td-agent_2.pid --config /etc/td-agent/td-agent_2.conf",83 "root 145 142 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_2.log --daemon /var/run/td-agent/td-agent_2.pid --config /etc/td-agent/td-agent_2.conf --under-supervisor",84 "root 152 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_3.log --daemon /var/run/td-agent/td-agent_3.pid --config /etc/td-agent/td-agent_3.conf",85 "root 155 152 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_3.log --daemon /var/run/td-agent/td-agent_3.pid --config /etc/td-agent/td-agent_3.conf --under-supervisor",86 "root 163 1 0 03:44 ? 00:00:00 supervisor:foo_a",87 "root 166 163 0 03:44 ? 00:00:01 worker:foo_a",88 "root 175 1 0 03:45 ? 00:00:00 supervisor:foo_b",89 "root 178 175 0 03:45 ? 00:00:01 worker:foo_b",90 "root 186 1 0 03:45 ? 00:00:00 supervisor:foo_c",91 "root 189 186 0 03:45 ? 00:00:01 worker:foo_c",92 "root 191 1 0 03:45 pts/0 00:00:01 worker:from_fluentd",93 "root 193 1 0 03:45 pts/0 00:00:01 worker:from_td_agent",94 }95 processName := "foo"96 processNamePrefix = &processName97 exporter := NewExporter()98 filtered := exporter.filter(lines)99 log.Info(filtered)100 if len(filtered) != 5 {101 t.Error("filtered array len doesn't match")102 }103}104func TestUnitResolveLabelWithConfigFileName(t *testing.T) {105 lines := []string{106 "UID PID PPID C STIME TTY TIME CMD",107 "root 1 0 0 03:43 pts/0 00:00:00 /bin/bash",108 "root 115 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid",109 "root 118 115 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid --under-supervisor",110 "root 125 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_1.log --daemon /var/run/td-agent/td-agent_1.pid --config /etc/td-agent/td-agent_1.conf",111 "root 128 125 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_1.log --daemon /var/run/td-agent/td-agent_1.pid --config /etc/td-agent/td-agent_1.conf --under-supervisor",112 "root 142 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_2.log --daemon /var/run/td-agent/td-agent_2.pid --config /etc/td-agent/td-agent_2.conf",113 "root 145 142 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_2.log --daemon /var/run/td-agent/td-agent_2.pid --config /etc/td-agent/td-agent_2.conf --under-supervisor",114 "root 152 1 0 03:44 ? 00:00:00 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_3.log --daemon /var/run/td-agent/td-agent_3.pid --config /etc/td-agent/td-agent_3.conf",115 "root 155 152 0 03:44 ? 00:00:01 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_3.log --daemon /var/run/td-agent/td-agent_3.pid --config /etc/td-agent/td-agent_3.conf --under-supervisor",116 }117 processName := ""118 processNamePrefix = &processName119 exporter := NewExporter()120 labels := exporter.resolveTdAgentIdWithConfigFileName(lines)121 log.Info(labels)122 if len(labels) != 4 {123 t.Error("labels size doesn't match")124 }125 if value, ok := labels["default"]; !ok &&126 value == "/opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid" {127 t.Error("labels `default` doesn't exist")128 }129 if value, ok := labels["td-agent_1"]; !ok &&130 value == "/opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_1.log --daemon /var/run/td-agent/td-agent_1.pid --config /etc/td-agent/td-agent_1.conf" {131 t.Error("labels `td-agent_1` doesn't exist")132 }133 if value, ok := labels["td-agent_2"]; !ok &&134 value == "/opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_2.log --daemon /var/run/td-agent/td-agent_2.pid --config /etc/td-agent/td-agent_2.conf" {135 t.Error("labels `td-agent_2` doesn't exist")136 }137 if value, ok := labels["td-agent_3"]; !ok &&138 value == "/opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent_3.log --daemon /var/run/td-agent/td-agent_3.pid --config /etc/td-agent/td-agent_3.conf" {139 t.Error("labels `td-agent_3` doesn't exist")140 }141}142func TestUnitResolveLabelWithProcessNamePrefix(t *testing.T) {143 lines := []string{144 "root 166 163 0 03:44 ? 00:00:01 worker:foo_a",145 "root 178 175 0 03:45 ? 00:00:01 worker:foo_b ",146 }147 processName := "foo"148 processNamePrefix = &processName149 exporter := NewExporter()150 labels, _ := exporter.resolveTdAgentIdWithProcessNamePrefix(lines)151 log.Info(labels)152 if len(labels) != 2 {153 t.Error("labels size doesn't match")154 }155 if _, ok := labels["foo_a"]; !ok {156 t.Error("labels `foo_a` doesn't exist")157 }158 if _, ok := labels["foo_b"]; !ok {159 t.Error("labels `foo_b` doesn't exist")160 }161}162// e2e test163func TestE2EWithoutProcessNamePrefix(t *testing.T) {164 time.Sleep(1 * time.Second)165 metrics, err := get("http://localhost:9256/metrics")166 if err != nil {167 t.Errorf("HttpClient.Get = %v", err)168 }169 log.Info(metrics)170 // td_agent_cpu_time171 if !regexp.MustCompile(`td_agent_cpu_time{id="default"} `).MatchString(metrics) {172 t.Error(`td_agent_cpu_time{id="default"} doesn't match`)173 }174 if !regexp.MustCompile(`td_agent_cpu_time{id="td-agent_1"} `).MatchString(metrics) {175 t.Error(`td_agent_cpu_time{id="td-agent_1"} doesn't match`)176 }177 if !regexp.MustCompile(`td_agent_cpu_time{id="td-agent_2"} `).MatchString(metrics) {178 t.Error(`td_agent_cpu_time{id="td-agent_2"} doesn't match`)179 }180 if !regexp.MustCompile(`td_agent_cpu_time{id="td-agent_3"} `).MatchString(metrics) {181 t.Error(`td_agent_cpu_time{id="td-agent_3"} doesn't match`)182 }183 // td_agent_resident_memory_usage184 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="default"} `).MatchString(metrics) {185 t.Error(`td_agent_resident_memory_usage{id="default"} doesn't match`)186 }187 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="td-agent_1"} `).MatchString(metrics) {188 t.Error(`td_agent_resident_memory_usage{id="td-agent_1"} doesn't match`)189 }190 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="td-agent_2"} `).MatchString(metrics) {191 t.Error(`td_agent_resident_memory_usage{id="td-agent_2"} doesn't match`)192 }193 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="td-agent_3"} `).MatchString(metrics) {194 t.Error(`td_agent_resident_memory_usage{id="td-agent_3"} doesn't match`)195 }196 // td_agent_virtual_memory_usage197 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="default"} `).MatchString(metrics) {198 t.Error(`td_agent_virtual_memory_usage{id="default"} doesn't match`)199 }200 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="td-agent_1"} `).MatchString(metrics) {201 t.Error(`td_agent_virtual_memory_usage{id="td-agent_1"} doesn't match`)202 }203 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="td-agent_2"} `).MatchString(metrics) {204 t.Error(`td_agent_virtual_memory_usage{id="td-agent_2"} doesn't match`)205 }206 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="td-agent_3"} `).MatchString(metrics) {207 t.Error(`td_agent_virtual_memory_usage{id="td-agent_3"} doesn't match`)208 }209 // td_agent_up210 if !regexp.MustCompile("td_agent_up 4").MatchString(metrics) {211 t.Error("td_agent_up doesn't match")212 }213 // Different process file name processes are not mathed.214 if regexp.MustCompile(`td_agent_cpu_time{id="from_fluentd"} `).MatchString(metrics) {215 t.Error("Process from /opt/td-agent/embedded/bin/fluentd shouldn't match")216 }217 if regexp.MustCompile(`td_agent_cpu_time{id="from_td-agent"} `).MatchString(metrics) {218 t.Error("Process from /opt/td-agent/bin/fluentd shouldn't match")219 }220}221func TestE2EWithProcessNamePrefix(t *testing.T) {222 time.Sleep(1 * time.Second)223 metrics, err := get("http://localhost:19256/metrics")224 if err != nil {225 t.Errorf("HttpClient.Get = %v", err)226 }227 log.Info(metrics)228 // td_agent_cpu_time229 if !regexp.MustCompile(`td_agent_cpu_time{id="foo_a"} `).MatchString(metrics) {230 t.Error(`td_agent_cpu_time{id="foo_a"} doesn't match`)231 }232 if !regexp.MustCompile(`td_agent_cpu_time{id="foo_b"} `).MatchString(metrics) {233 t.Error(`td_agent_cpu_time{id="foo_b"} doesn't match`)234 }235 // td_agent_resident_memory_usage236 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="foo_a"} `).MatchString(metrics) {237 t.Error(`td_agent_resident_memory_usage{id="foo_a"} doesn't match`)238 }239 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="foo_b"} `).MatchString(metrics) {240 t.Error(`td_agent_resident_memory_usage{id="foo_b"} doesn't match`)241 }242 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="foo_c"} `).MatchString(metrics) {243 t.Error(`td_agent_resident_memory_usage{id="foo_c"} doesn't match`)244 }245 // td_agent_virtual_memory_usage246 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="foo_a"} `).MatchString(metrics) {247 t.Error(`td_agent_virtual_memory_usage{id="foo_a"} doesn't match`)248 }249 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="foo_b"} `).MatchString(metrics) {250 t.Error(`td_agent_virtual_memory_usage{id="foo_b"} doesn't match`)251 }252 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="foo_c"} `).MatchString(metrics) {253 t.Error(`td_agent_virtual_memory_usage{id="foo_c"} doesn't match`)254 }255 // td_agent_up256 if !regexp.MustCompile("td_agent_up 3").MatchString(metrics) {257 t.Error("td_agent_up doesn't match")258 }259}260func TestE2EWithProcessFileNameFluentd(t *testing.T) {261 time.Sleep(1 * time.Second)262 metrics, err := get("http://localhost:29256/metrics")263 if err != nil {264 t.Errorf("HttpClient.Get = %v", err)265 }266 log.Info(metrics)267 // td_agent_cpu_time268 if !regexp.MustCompile(`td_agent_cpu_time{id="from_fluentd"} `).MatchString(metrics) {269 t.Error(`td_agent_cpu_time{id="from_fluentd"} doesn't match`)270 }271 // td_agent_resident_memory_usage272 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="from_fluentd"} `).MatchString(metrics) {273 t.Error(`td_agent_resident_memory_usage{id="from_fluentd"} doesn't match`)274 }275 // td_agent_virtual_memory_usage276 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="from_fluentd"} `).MatchString(metrics) {277 t.Error(`td_agent_virtual_memory_usage{id="from_fluentd"} doesn't match`)278 }279 // td_agent_up280 if !regexp.MustCompile("td_agent_up 1").MatchString(metrics) {281 t.Error("td_agent_up doesn't match")282 }283}284func TestE2EWithProcessFileNameTDAgent(t *testing.T) {285 time.Sleep(1 * time.Second)286 metrics, err := get("http://localhost:39256/metrics")287 if err != nil {288 t.Errorf("HttpClient.Get = %v", err)289 }290 log.Info(metrics)291 // td_agent_cpu_time292 if !regexp.MustCompile(`td_agent_cpu_time{id="from_td_agent"} `).MatchString(metrics) {293 t.Error(`td_agent_cpu_time{id="from_td_agent"} doesn't match`)294 }295 // td_agent_resident_memory_usage296 if !regexp.MustCompile(`td_agent_resident_memory_usage{id="from_td_agent"} `).MatchString(metrics) {297 t.Error(`td_agent_resident_memory_usage{id="from_td_agent"} doesn't match`)298 }299 // td_agent_virtual_memory_usage300 if !regexp.MustCompile(`td_agent_virtual_memory_usage{id="from_td_agent"} `).MatchString(metrics) {301 t.Error(`td_agent_virtual_memory_usage{id="from_td_agent"} doesn't match`)302 }303 // td_agent_up304 if !regexp.MustCompile("td_agent_up 1").MatchString(metrics) {305 t.Error("td_agent_up doesn't match")306 }307}308func get(url string) (string, error) {309 log.Info(url)310 response, err := http.Get(url)311 if err != nil {312 log.Errorf("http.Get = %v", err)313 return "", err314 }315 defer response.Body.Close()316 body, err := ioutil.ReadAll(response.Body)317 if err != nil {318 log.Errorf("ioutil.ReadAll = %v", err)319 return "", err320 }321 if response.StatusCode != 200 {322 log.Errorf("response.StatusCode = %v", response.StatusCode)323 return "", err324 }325 metrics := string(body)326 return metrics, nil327}...
episodes.go
Source:episodes.go
1package main2import (3 "encoding/json"4 "fmt"5 "io/ioutil"6 "net/http"7 "os"8 "regexp"9 "sort"10 "strconv"11 "strings"12 "sync"13 "time"14 "github.com/pborman/getopt"15 yaml "gopkg.in/yaml.v2"16)17const (18 crlf = "\r\n"19 wikiPath = "https://en.wikipedia.org/wiki/"20)21func cleanWiki(clean string) string {22 messy := []string{"? ", ": ", "... "}23 for _, ugly := range messy {24 clean = strings.Replace(clean, ugly, " - ", -1)25 }26 dirty := []string{"!", "?", "&", "[", "]", "'", "...",27 "<b>", "</b>", "<i>", "</i>"}28 for _, dirt := range dirty {29 clean = strings.Replace(clean, dirt, "", -1)30 }31 comma := []string{"\"", "<"}32 for _, char := range comma {33 clean = strings.Split(clean, char)[0]34 }35 return clean36}37func processWiki(show string) {38 var episodes = map[int]string{}39 fmt.Println("Processing", show)40 data, err := ioutil.ReadFile(show + ".wiki")41 if err != nil {42 panic(err)43 }44 sep := "\n"45 if strings.HasPrefix(string(data), crlf) {46 sep = crlf47 } else if strings.HasPrefix(string(data), "\r") {48 sep = "\r"49 }50 var season int = 051 var lines []string52 lines = strings.Split(string(data), sep)53 for _, line := range lines {54 if strings.HasPrefix(line, "Season ") || strings.HasPrefix(line, "Series ") {55 //fmt.Printf("%d : %s\n", index, line)56 r := regexp.MustCompile("^(Season|Series) ([0-9]+).*$")57 season, _ = strconv.Atoi(r.ReplaceAllString(line, "$2"))58 //fmt.Println("Season:", 100 * season)59 }60 clean := cleanWiki(line)61 single := regexp.MustCompile("^[0-9]+[^0-9]+([0-9]+)[^0-9]+\"([^\"]+)\".*$")62 if single.MatchString(clean) {63 if season > 0 {64 ep := strings.Split(single.ReplaceAllString(clean, "$1|$2"), "|")65 num, err := strconv.Atoi(ep[0])66 if err == nil {67 //fmt.Println("Episode:", 100 * season + num, ep[1], line)68 episodes[100*season+num] = ep[1]69 }70 }71 }72 }73 //fmt.Println("Episodes:", episodes)74 output, _ := json.MarshalIndent(episodes, "", " ")75 ioutil.WriteFile(show+".json", output, 0644)76}77func buildMove(show string) {78 var episodes = map[int]string{}79 fmt.Println("Building", show)80 data, err := ioutil.ReadFile(show + ".list")81 if err != nil {82 panic(err)83 }84 var moves []string85 var lines []string86 lines = strings.Split(string(data), crlf)87 for _, line := range lines {88 pos := strings.LastIndex(line, "Season ")89 off := len(line) - pos90 if strings.Contains(line, "\\Season ") && off > 10 {91 //fmt.Printf("%v : %s\n", index, line[pos:])92 var num int = 093 type2 := regexp.MustCompile("^.*[Ss]([0-9]+)[Ee]([0-9]+).*$")94 type3 := regexp.MustCompile("^.*([0-9]+)x([0-9]+).*$")95 if type2.MatchString(line) {96 num, _ = strconv.Atoi(type2.ReplaceAllString(line, "$1$2"))97 } else if type3.MatchString(line) {98 num, _ = strconv.Atoi(type3.ReplaceAllString(line, "$1$2"))99 }100 if num > 0 {101 season := strings.Split(line[pos:], "\\")[0]102 dots := strings.Split(line[pos:], ".")103 ext := dots[len(dots)-1]104 moves = append(moves, fmt.Sprintf("move \"%s\" \"%s\\%d - %s.%s\"", line[pos:], season, num, episodes[num], ext))105 }106 }107 }108 output := fmt.Sprintf("%s%spause%s", strings.Join(moves, crlf), crlf, crlf)109 ioutil.WriteFile(show+".cmd", []byte(output), 0644)110}111func buildList(show string) {112 fmt.Println("Reading", show)113 //data, err := filepath.Glob("*")114 data, err := ioutil.ReadDir("./")115 if err != nil {116 panic(err)117 }118 var files []string119 for _, d := range data {120 if strings.HasPrefix(d.Name(), "Season ") {121 season, _ := ioutil.ReadDir(d.Name())122 for _, f := range season {123 files = append(files, fmt.Sprintf("\\%s\\%s", d.Name(), f.Name()))124 }125 }126 }127 //fmt.Println("Files:", strings.Join(files, crlf))128 output := fmt.Sprintf("%s%s", strings.Join(files, crlf), crlf)129 ioutil.WriteFile(show+".list", []byte(output), 0644)130}131func parseWiki(show string, uri string, textOut bool, debug bool, rules *Rule) {132 var episodes = map[int]string{}133 var schedule = map[int]string{}134 fmt.Println("Parsing", uri)135 //fmt.Println("Rules", rules)136 client := &http.Client{}137 req, _ := http.NewRequest("GET", wikiPath+uri, nil)138 resp, _ := client.Do(req)139 defer resp.Body.Close()140 data, err := ioutil.ReadAll(resp.Body)141 if err != nil {142 fmt.Println(err)143 os.Exit(1)144 }145 //fmt.Println(os.Stdout, string(data))146 var title string = ""147 var season int = 1148 var number string = ""149 var episode int = 0150 var active bool = false151 var eis bool = false152 s := regexp.MustCompile(rules.Season)153 n := regexp.MustCompile(rules.Number)154 e := regexp.MustCompile(rules.Episode)155 t := regexp.MustCompile(rules.Title)156 v := regexp.MustCompile(rules.Versus)157 h := regexp.MustCompile(rules.Hyper)158 d := regexp.MustCompile(rules.Datum)159 a := regexp.MustCompile(rules.Alpha)160 var lines []string161 lines = strings.Split(string(data), "\n")162 for _, line := range lines {163 if strings.Contains(line, "id=\"Episode") {164 active = true165 } else if strings.Contains(line, "<h2>") {166 active = false167 }168 if active {169 //fmt.Printf("%d : %s\n", index, line)170 if debug {171 fmt.Printf("LINE : %s\n", line)172 }173 if strings.Contains(line, "class=\"mw-headline\"") {174 season = 0 // zero Season during Movie headers and Specials175 if debug {176 fmt.Println("SEASON: Movie Specials")177 }178 }179 if s.MatchString(line) {180 if s.ReplaceAllString(line, "$2") == "" {181 season = 1 // Episodes182 } else {183 season, _ = strconv.Atoi(s.ReplaceAllString(line, "$2"))184 }185 if debug {186 fmt.Println("SEASON:", season)187 }188 }189 if n.MatchString(line) {190 number = n.ReplaceAllString(line, "$1")191 if debug {192 fmt.Println("NUMBER:", number)193 }194 eis = true // episode-in-season195 }196 if eis && e.MatchString(line) {197 episode, _ = strconv.Atoi(e.ReplaceAllString(line, "$1"))198 if debug {199 fmt.Println("EPISODE:", episode)200 }201 eis = false202 } else {203 episode, _ = strconv.Atoi(number)204 }205 if t.MatchString(line) || v.MatchString(line) {206 if v.MatchString(line) {207 title = v.ReplaceAllString(line, "$1 vs $2")208 if debug {209 fmt.Println("VERSUS:", title)210 }211 } else if t.MatchString(line) {212 title = t.ReplaceAllString(line, "$1")213 if debug {214 fmt.Println("TITLE:", title)215 }216 if h.MatchString(title) {217 title = h.ReplaceAllString(title, "$1")218 if debug {219 fmt.Println("HYPER:", title)220 }221 }222 }223 if len(title) > 0 && episode > 0 {224 key := 100*season + episode225 episodes[key] = cleanWiki(title)226 schedule[key] = "TBA"227 }228 }229 if a.MatchString(line) || d.MatchString(line) {230 var timestamp string231 if d.MatchString(line) {232 timestamp = d.ReplaceAllString(line, "$1 $2, $3")233 } else if a.MatchString(line) {234 timestamp = a.ReplaceAllString(line, "$2 $1, $3")235 }236 if debug {237 fmt.Println("AIRING:", timestamp)238 //fmt.Printf("%s %s: %s on %s\n", season, episode, title, timestamp)239 }240 if len(title) > 0 && episode > 0 {241 key := 100*season + episode242 raw, _ := time.Parse("January 2, 2006", timestamp)243 if raw.Year() == time.Now().Year() {244 schedule[key] = fmt.Sprintf("%02d/%02d", raw.Month(), raw.Day())245 } else {246 schedule[key] = fmt.Sprintf("%04d/%02d/%02d", raw.Year(), raw.Month(), raw.Day())247 }248 }249 }250 }251 }252 if textOut {253 var text []string254 keys := make([]int, 0)255 for k, _ := range episodes {256 keys = append(keys, k)257 }258 sort.Ints(keys)259 for _, k := range keys {260 text = append(text, fmt.Sprintf("%s\t%d - %s", schedule[k], k, episodes[k]))261 }262 var timeline string263 if len(text) > 0 {264 timeline = strings.Join(text, crlf)265 } else {266 timeline = string(data)267 }268 ioutil.WriteFile(show+".txt", []byte(timeline), 0644)269 } else {270 //fmt.Println("Episodes:", episodes)271 output, _ := json.MarshalIndent(episodes, "", " ")272 ioutil.WriteFile(show+".json", output, 0644)273 }274}275type Rule struct {276 Season string277 Number string278 Episode string279 Title string280 Versus string281 Hyper string282 Datum string283 Alpha string284}285type Show struct {286 Name string287 Wiki string288}289type Settings struct {290 Rules Rule291 Shows []Show292}293func parseYaml(config string, debug bool) {294 fmt.Println("Parsing", config)295 data, err := ioutil.ReadFile(config + ".yaml")296 if err != nil {297 panic(err)298 }299 var settings Settings300 err = yaml.Unmarshal(data, &settings)301 if err != nil {302 panic(err)303 }304 showLength := len(settings.Shows)305 var wg sync.WaitGroup306 wg.Add(showLength)307 fmt.Printf("Found %d shows\n", showLength)308 /*309 for _, show := range settings.Shows {310 fmt.Println("Processing", show.Name, show.Wiki)311 }312 */313 for i := 0; i < showLength; i++ {314 go func(i int) {315 defer wg.Done()316 show := settings.Shows[i]317 //fmt.Println("Processing", show.Name, show.Wiki)318 parseWiki(show.Name, show.Wiki, true, debug, &settings.Rules)319 }(i)320 }321 wg.Wait()322 fmt.Printf("Processed %d shows\n", showLength)323}324func main() {325 optDbug := getopt.BoolLong("dbug", 'd', "Debug")326 optHelp := getopt.BoolLong("help", 'h', "Help")327 optList := getopt.BoolLong("list", 'l', "Process File List")328 optRead := getopt.BoolLong("read", 'r', "Read Current Dir")329 optTime := getopt.BoolLong("time", 't', "Output Time Text")330 optName := getopt.StringLong("name", 'n', "", "TV Show name (required)")331 optWiki := getopt.StringLong("wiki", 'w', "", "Wiki Page Name")332 optYaml := getopt.BoolLong("yaml", 'y', "Load YAML Config (name)")333 getopt.Parse()334 if *optHelp || len(os.Args) < 2 {335 getopt.Usage()336 os.Exit(0)337 }338 //fmt.Printf("Name: %v, Wiki: %v, Read: %v, List: %v\n", *optName, *optWiki, *optRead, *optList)339 if len(*optName) > 0 {340 if *optYaml {341 parseYaml(*optName, *optDbug)342 } else if len(*optWiki) < 1 {343 processWiki(*optName)344 } else {345 rules := &Rule{346 Season: "^.*class=\"mw-headline\" id=\"(Season|Series)_([0-9]+).*$",347 Number: "^.*th scope=\"row\"(?: rowspan=\"[0-9]+\")? id=\"ep([0-9]+)\".*$",348 Episode: "^.*<td style=\"text-align:center\">([0-9]+)</td>.*(?:class=\"summary\").*$",349 Title: "^.*>[0-9]+</td><td class=\"summary\" style=\"text-align:left\">\"(.+).*</td.*$",350 Versus: "^.*td class=\"summary\" style=\"text-align:left\">.*title=\"(.+)\".+vs.+title=\"(.+)\".+</td.*$",351 Hyper: "<a href=\".+\">(.+)</a>\"",352 Datum: "^.*<td style=\"text-align:center\">([A-Za-z]+) ([0-9]+), ([0-9]+)<span.+bday dtstart.+$",353 Alpha: "^.*<td style=\"text-align:center\">([0-9]+) ([A-Za-z]+) ([0-9]+)<span.+bday dtstart.+$",354 }355 parseWiki(*optName, *optWiki, *optTime, *optDbug, rules)356 }357 if *optList {358 buildMove(*optName)359 } else if *optRead {360 buildList(*optName)361 buildMove(*optName)362 }363 } else {364 getopt.Usage()365 }366}...
getlyrics.go
Source:getlyrics.go
1package main2import (3 "github.com/kennygrant/sanitize"4 "regexp"5)6/*7 * defined functions8 */9// get lyrics from "www.jtw.zaq.ne.jp"10func GetLyricsOmakase(url string, id int) LyricsData {11 regTitle := regexp.MustCompile("(?is)<title>(.*?)</title>")12 regInfo := regexp.MustCompile("(?is).*?ä½è©[:ï¼](.*?)ï¼ä½æ²[:ï¼](.*?)ï¼ç·¨æ²[:ï¼](.*?)ï¼\næ[:ï¼](.*?)\n\n(.*?)</pre></td>")13 title := ""14 singer := ""15 lyricist := ""16 composer := ""17 arranger := ""18 lyrics := ""19 errCount := 020 html := ""21 for errCount < 5 {22 html1, err := GetHTML(url)23 html = html124 if err != nil {25 errCount++26 } else {27 html, _ = sjis_to_utf8(html)28 break29 }30 }31 if regTitle.MatchString(html) {32 group := regTitle.FindStringSubmatch(html)33 title = group[1]34 }35 if regInfo.MatchString(html) {36 group := regInfo.FindStringSubmatch(html)37 lyricist = group[1]38 composer = group[2]39 arranger = group[3]40 singer = group[4]41 lyrics = group[5]42 }43 data := LyricsData{44 ID: id,45 Title: title,46 Lyricist: lyricist,47 Composer: composer,48 Arranger: arranger,49 Singer: singer,50 Lyrics: lyrics,51 }52 return data53}54// get lyrics from "www.kasi-time.com"55func GetLyricsKasiTime(url string, id int) LyricsData {56 regUrl := regexp.MustCompile(`www.kasi-time.com/item-(.*?).html`)57 regTitle := regexp.MustCompile(`(?is)<div id="song_info_table">.*?<h1>(.*?)</h1>`)58 regPronounce := regexp.MustCompile(`(?is)<td class="td2">èªã¿</td>.*?<td>(.*?)</td>`)59 regInfo := regexp.MustCompile(`(?is)<meta name="description" content="ææ:(.*?)[ ã]+ä½è©:(.*?)[ ã]+ä½æ²:(.*?)[ ã]+.*?>`)60 regArranger := regexp.MustCompile(`(?is)<td class="td1">ç·¨æ²</td>.*?<td>(.*?)</td>`)61 regLyrics := regexp.MustCompile(`document.write\('(.+)'\);`)62 baseUrl := "http://www.kasi-time.com/item_js.php?no="63 pageUrl := baseUrl64 title := ""65 pronounce := ""66 singer := ""67 lyricist := ""68 composer := ""69 arranger := ""70 lyrics := ""71 if regUrl.MatchString(url) {72 group := regUrl.FindStringSubmatch(url)73 pageID := group[1]74 pageUrl += pageID75 }76 html1 := ""77 html2 := ""78 errCount1 := 079 errCount2 := 080 for errCount1 < 5 {81 html, err := GetHTML(url)82 html1 = html83 if err != nil {84 errCount1++85 } else {86 break87 }88 }89 for errCount2 < 5 {90 html, err := GetHTML(pageUrl)91 html2 = html92 if err != nil {93 errCount1++94 } else {95 break96 }97 }98 if regTitle.MatchString(html1) {99 group := regTitle.FindStringSubmatch(html1)100 title = group[1]101 }102 if regPronounce.MatchString(html1) {103 group := regPronounce.FindStringSubmatch(html1)104 pronounce = group[1]105 }106 if regInfo.MatchString(html1) {107 group := regInfo.FindStringSubmatch(html1)108 singer = group[1]109 lyricist = group[2]110 composer = group[3]111 }112 if regArranger.MatchString(html1) {113 group := regArranger.FindStringSubmatch(html1)114 arranger = sanitize.HTML(group[1])115 }116 if regLyrics.MatchString(html2) {117 group := regLyrics.FindStringSubmatch(html2)118 lyrics = sanitize.HTML(group[1])119 }120 data := LyricsData{121 ID: id,122 Title: title,123 Pronounce: pronounce,124 Singer: singer,125 Lyricist: lyricist,126 Composer: composer,127 Arranger: arranger,128 Lyrics: lyrics,129 }130 return data131}...
matchString
Using AI Code Generation
1import (2func main() {3re := regexp.MustCompile("a([a-z]+)e")4fmt.Println(re.MatchString("apple"))5fmt.Println(re.MatchString("ape"))6}7import (8func main() {9re := regexp.MustCompile("a([a-z]+)e")10fmt.Println(re.FindString("apple"))11fmt.Println(re.FindString("ape"))12}13import (14func main() {15re := regexp.MustCompile("a([a-z]+)e")16fmt.Println(re.FindStringIndex("apple"))17fmt.Println(re.FindStringIndex("ape"))18}19import (20func main() {21re := regexp.MustCompile("a([a-z]+)e")22fmt.Println(re.FindStringSubmatch("apple"))23fmt.Println(re.FindStringSubmatch("ape"))24}25import (26func main() {27re := regexp.MustCompile("a([a-z]+)e")28fmt.Println(re.FindStringSubmatchIndex("apple"))29fmt.Println(re.FindStringSubmatchIndex("ape"))30}31import (32func main() {33re := regexp.MustCompile("a([a-z]+)e")34fmt.Println(re.FindAllString("apple pear", -1))35}36import (37func main() {38re := regexp.MustCompile("a([a-z]+)e")39fmt.Println(re
matchString
Using AI Code Generation
1import (2func main() {3 var pattern = regexp.MustCompile(`[a-z]+`)4 fmt.Println(pattern.MatchString(str))5}6import (7func main() {8 var pattern = regexp.MustCompile(`[a-z]+`)9 fmt.Println(pattern.FindString(str))10}11import (12func main() {13 var pattern = regexp.MustCompile(`[a-z]+`)14 fmt.Println(pattern.FindStringIndex(str))15}16import (17func main() {18 var pattern = regexp.MustCompile(`([a-z]+) ([a-z]+)`)19 fmt.Println(pattern.FindStringSubmatch(str))20}21import (22func main() {23 var pattern = regexp.MustCompile(`([a-z]+) ([a-z]+)`)24 fmt.Println(pattern.FindStringSubmatchIndex(str))25}26import (27func main() {28 var pattern = regexp.MustCompile(`[a-z]+`)29 fmt.Println(pattern.FindAllString(str, -1))30}
matchString
Using AI Code Generation
1import (2func main() {3 td := regexp.MustCompile(`\d{2}-\d{2}-\d{4}`)4 fmt.Println(td.MatchString("20-12-2012"))5}6import (7func main() {8 td := regexp.MustCompile(`\d{2}-\d{2}-\d{4}`)9 fmt.Println(td.FindString("20-12-2012"))10}11import (12func main() {13 td := regexp.MustCompile(`\d{2}-\d{2}-\d{4}`)14 fmt.Println(td.FindStringIndex("20-12-2012"))15}16import (17func main() {18 td := regexp.MustCompile(`(\d{2})-(\d{2})-(\d{4})`)19 fmt.Println(td.FindStringSubmatch("20-12-2012"))20}21import (22func main() {23 td := regexp.MustCompile(`(\d{2})-(\d{2})-(\d{4})`)24 fmt.Println(td.FindStringSubmatchIndex("20-12-2012"))25}26import (27func main() {28 td := regexp.MustCompile(`\d{2}-\d{2}-\d{4}`)29 fmt.Println(td.FindAllString("20-12-2012 21-12-2012", -1))30}
matchString
Using AI Code Generation
1import (2func main() {3 td := regexp.MustCompile(`\d+`)4 fmt.Println(td.MatchString("123"))5 fmt.Println(td.MatchString("abc"))6}7import (8func main() {9 td := regexp.MustCompile(`\d+`)10 fmt.Println(td.FindString("123"))11 fmt.Println(td.FindString("abc"))12}13import (14func main() {15 td := regexp.MustCompile(`\d+`)16 fmt.Println(td.FindStringIndex("123"))17 fmt.Println(td.FindStringIndex("abc"))18}19import (20func main() {21 td := regexp.MustCompile(`(\d+)([a-z]+)`)22 fmt.Println(td.FindStringSubmatch("123abc"))23 fmt.Println(td.FindStringSubmatch("abc"))24}25import (26func main() {27 td := regexp.MustCompile(`(\d+)([a-z]+)`)28 fmt.Println(td.FindStringSubmatchIndex("123abc"))29 fmt.Println(td.FindStringSubmatchIndex("abc"))30}31import (32func main() {33 td := regexp.MustCompile(`\d+`)34 fmt.Println(td.FindAllString("123abc456", -1))35 fmt.Println(td.FindAllString("abc", -1))36}37import (38func main() {39 td := regexp.MustCompile(`\d
matchString
Using AI Code Generation
1import (2func main() {3 fmt.Println("Match String Method")4 fmt.Println(regexp.MatchString("p([a-z]+)ch", "peach"))5 fmt.Println(regexp.MatchString("p([a-z]+)ch", "peach punch"))6 fmt.Println(regexp.MatchString("p([a-z]+)ch", "peach punch peach punch"))7 fmt.Println("Compile Method")8 r, _ := regexp.Compile("p([a-z]+)ch")9 fmt.Println(r.MatchString("peach"))10 fmt.Println(r.FindString("peach punch"))11 fmt.Println(r.FindStringIndex("peach punch"))12 fmt.Println(r.FindStringSubmatch("peach punch"))13 fmt.Println(r.FindStringSubmatchIndex("peach punch"))14 fmt.Println(r.FindAllString("peach punch pinch", -1))15 fmt.Println(r.FindAllStringSubmatchIndex("peach punch pinch", -1))16 fmt.Println(r.FindAllString("peach punch pinch", 2))17 fmt.Println(r.Match([]byte("peach")))18 fmt.Println(r.Find([]byte("peach punch")))19 fmt.Println(r.FindIndex([]byte("peach punch")))20 fmt.Println(r.FindSubmatch([]byte("peach punch")))21 fmt.Println(r.FindSubmatchIndex([]byte("peach punch")))22 fmt.Println(r.FindAll([]byte("peach punch pinch"), -1))23 fmt.Println(r.FindAllSubmatchIndex([]byte("peach punch pinch"), -1))24 fmt.Println(r.FindAll([]byte("peach punch pinch"), 2))25 fmt.Println("Must Compile Method")26 r = regexp.MustCompile("p([a-z]+)ch")27 fmt.Println(r)28 fmt.Println("Replace All String Method")29 fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))30 fmt.Println("Replace All String Func Method")31 in := []byte("a peach")32 out := r.ReplaceAllFunc(in, bytes.ToUpper)33 fmt.Println(string(out))34}
matchString
Using AI Code Generation
1import (2func main() {3 td := regexp.MustCompile("^[a-z][a-z0-9_]*[a-z0-9]$")4 fmt.Println(td.MatchString("abc"))5 fmt.Println(td.MatchString("123"))6 fmt.Println(td.MatchString("abc_123"))7 fmt.Println(td.MatchString("abc_123_"))8 fmt.Println(td.MatchString("1abc"))9 fmt.Println(td.MatchString("abc_"))10}11import (12func main() {13 td := regexp.MustCompile("^[a-z][a-z0-9_]*[a-z0-9]$")14 fmt.Println(td.ReplaceAllString("abc", "123"))15 fmt.Println(td.ReplaceAllString("123", "456"))16 fmt.Println(td.ReplaceAllString("abc_123", "xyz_456"))17 fmt.Println(td.ReplaceAllString("abc_123_", "xyz_456_"))18 fmt.Println(td.ReplaceAllString("1abc", "789"))19 fmt.Println(td.ReplaceAllString("abc_", "xyz_"))20}21import (22func main() {23 td := regexp.MustCompile("^[a-z][a-z0-9_]*[a-z0-9]$")24 fmt.Println(td.ReplaceAllStringFunc("abc", strings.ToUpper))25 fmt.Println(td.ReplaceAllStringFunc("123", strings.ToUpper))26 fmt.Println(td.ReplaceAllStringFunc("abc_123", strings.ToUpper))27 fmt.Println(td.ReplaceAllStringFunc("abc_123_", strings.ToUpper))28 fmt.Println(td.ReplaceAllStringFunc("1abc", strings.ToUpper))29 fmt.Println(td.ReplaceAllStringFunc("abc_", strings.ToUpper))30}31import (32func main() {33 td := regexp.MustCompile("^[a-z][a-z0-9_]*[a-z0-9]$
matchString
Using AI Code Generation
1import (2func main() {3 var regex, _ = regexp.Compile("Hello")4 var isMatch = regex.MatchString(str)5 fmt.Println(isMatch)6}7import (8func main() {9 var regex, _ = regexp.Compile("Hello")10 var isMatch = regex.FindString(str)11 fmt.Println(isMatch)12}13import (14func main() {15 var regex, _ = regexp.Compile("Hello")16 var isMatch = regex.FindStringIndex(str)17 fmt.Println(isMatch)18}19import (20func main() {21 var regex, _ = regexp.Compile("Hello")22 var isMatch = regex.FindStringSubmatch(str)23 fmt.Println(isMatch)24}25import (26func main() {27 var regex, _ = regexp.Compile("Hello")28 var isMatch = regex.FindStringSubmatchIndex(str)29 fmt.Println(isMatch)30}31import (32func main() {33 var regex, _ = regexp.Compile("Hello")34 var isMatch = regex.FindAllString(str, -1)35 fmt.Println(isMatch)36}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!