Example #1
0
func main() {
	// initialize logger
	log := logger.Logger()
	defer log.Close()
	defer log.Flush()

	// parse input parameters
	parseFlags(log)

	// check whether this is an interactive session
	isIntSess, err := svc.IsAnInteractiveSession()
	if err != nil {
		log.Warnf("Failed to determine if we are running in an interactive session: %v", err)
	}

	// isIntSess is false by default (after declaration), this fits the use
	// case that agent is running as Windows service most of times
	switch isIntSess {
	case true:
		run(log)
	case false:
		svc.Run(serviceName, &amazonSSMAgentService{log: log})
	}
}
Example #2
0
// Test provides a testing facility for alternative storage implementations.
// The s.setup should return a freshly created and empty storage. Removing the
// store from the system is the responsibility of the caller. The test only
// guarantees not to panic on recoverable errors and return an error instead.
// Test errors are not returned but reported to t.
func test(t *testing.T, s testDB) (panicked error) {
	defer func() {
		if e := recover(); e != nil {
			switch x := e.(type) {
			case error:
				panicked = x
			default:
				panicked = fmt.Errorf("%v", e)
			}
		}
		if panicked != nil {
			t.Errorf("PANIC: %v\n%s", panicked, debug.Stack())
		}
	}()

	db, err := s.setup()
	if err != nil {
		t.Error(err)
		return
	}

	tctx := NewRWCtx()
	if !*oSlow {
		if _, _, err := db.Execute(tctx, txBegin); err != nil {
			t.Error(err)
			return nil
		}
	}

	if err = s.mark(); err != nil {
		t.Error(err)
		return
	}

	defer func() {
		x := tctx
		if *oSlow {
			x = nil
		}
		if err = s.teardown(x); err != nil {
			t.Error(err)
		}
	}()

	chk := func(test int, err error, expErr string, re *regexp.Regexp) (ok bool) {
		s := err.Error()
		if re == nil {
			t.Error("FAIL: ", test, s)
			return false
		}

		if !re.MatchString(s) {
			t.Error("FAIL: ", test, "error doesn't match:", s, "expected", expErr)
			return false
		}

		return true
	}

	var logf *os.File
	hasLogf := false
	noErrors := true
	if _, ok := s.(*memTestDB); ok {
		if logf, err = ioutil.TempFile("", "ql-test-log-"); err != nil {
			t.Error(err)
			return nil
		}

		hasLogf = true
	} else {
		if logf, err = os.Create(os.DevNull); err != nil {
			t.Error(err)
			return nil
		}
	}

	defer func() {
		if hasLogf && noErrors {
			func() {
				if _, err := logf.Seek(0, 0); err != nil {
					t.Error(err)
					return
				}

				dst, err := os.Create("testdata.log")
				if err != nil {
					t.Error(err)
					return
				}

				if _, err := io.Copy(dst, logf); err != nil {
					t.Error(err)
					return
				}

				if err := dst.Close(); err != nil {
					t.Error(err)
				}
			}()
		}

		nm := logf.Name()
		if err := logf.Close(); err != nil {
			t.Error(err)
		}

		if hasLogf {
			if err := os.Remove(nm); err != nil {
				t.Error(err)
			}
		}
	}()

	log := bufio.NewWriter(logf)

	defer func() {
		if err := log.Flush(); err != nil {
			t.Error(err)
		}
	}()

	max := len(testdata)
	if n := *oM; n != 0 && n < max {
		max = n
	}
	for itest, test := range testdata[*oN:max] {
		//dbg("------------------------------------------------------------- ( itest %d ) ----", itest)
		var re *regexp.Regexp
		a := strings.Split(test+"|", "|")
		q, rset := a[0], strings.TrimSpace(a[1])
		var expErr string
		if len(a) < 3 {
			t.Error(itest, "internal error 066")
			return
		}

		if expErr = a[2]; expErr != "" {
			re = regexp.MustCompile("(?i:" + strings.TrimSpace(expErr) + ")")
		}

		q = strings.Replace(q, "&or;", "|", -1)
		q = strings.Replace(q, "&oror;", "||", -1)
		list, err := Compile(q)
		if err != nil {
			if !chk(itest, err, expErr, re) && *oFastFail {
				return
			}

			continue
		}

		for _, s := range list.l {
			if err := testMentionedColumns(s); err != nil {
				t.Error(itest, err)
				return
			}
		}

		s1 := list.String()
		list1, err := Compile(s1)
		if err != nil {
			t.Errorf("recreated source does not compile: %v\n---- orig\n%s\n---- recreated\n%s", err, q, s1)
			if *oFastFail {
				return
			}

			continue
		}

		s2 := list1.String()
		if g, e := s2, s1; g != e {
			t.Errorf("recreated source is not idempotent\n---- orig\n%s\n---- recreated1\n%s\n---- recreated2\n%s", q, s1, s2)
			if *oFastFail {
				return
			}

			continue
		}

		if !func() (ok bool) {
			tnl0 := db.tnl
			defer func() {
				s3 := list.String()
				if g, e := s1, s3; g != e {
					t.Errorf("#%d: execution mutates compiled statement list\n---- orig\n%s----new\n%s", itest, g, e)
				}

				if !ok {
					noErrors = false
				}

				if noErrors {
					hdr := false
					for _, v := range list.l {
						s, err := explained(db, v, tctx)
						if err != nil {
							t.Error(err)
							return
						}

						if !strings.HasPrefix(s, "┌") {
							continue
						}

						if !hdr {
							fmt.Fprintf(log, "---- %v\n", itest)
							hdr = true
						}
						fmt.Fprintf(log, "%s\n", v)
						fmt.Fprintf(log, "%s\n\n", s)
					}
				}

				tnl := db.tnl
				if tnl != tnl0 {
					panic(fmt.Errorf("internal error 057: tnl0 %v, tnl %v", tnl0, tnl))
				}

				nfo, err := db.Info()
				if err != nil {
					dbg("", err)
					panic(err)
				}

				for _, idx := range nfo.Indices {
					//dbg("#%d: cleanup index %s", itest, idx.Name)
					if _, _, err = db.run(tctx, fmt.Sprintf(`
						BEGIN TRANSACTION;
							DROP INDEX %s;
						COMMIT;
						`,
						idx.Name)); err != nil {
						t.Errorf("#%d: cleanup DROP INDEX %s: %v", itest, idx.Name, err)
						ok = false
					}
				}
				for _, tab := range nfo.Tables {
					//dbg("#%d: cleanup table %s", itest, tab.Name)
					if _, _, err = db.run(tctx, fmt.Sprintf(`
						BEGIN TRANSACTION;
							DROP table %s;
						COMMIT;
						`,
						tab.Name)); err != nil {
						t.Errorf("#%d: cleanup DROP TABLE %s: %v", itest, tab.Name, err)
						ok = false
					}
				}
				db.hasIndex2 = 0
			}()

			if err = s.mark(); err != nil {
				t.Error(err)
				return
			}

			rs, _, err := db.Execute(tctx, list, int64(30))
			if err != nil {
				return chk(itest, err, expErr, re)
			}

			if rs == nil {
				t.Errorf("FAIL: %d: expected non nil Recordset or error %q", itest, expErr)
				return
			}

			g, err := recSetDump(rs[len(rs)-1])
			if err != nil {
				return chk(itest, err, expErr, re)
			}

			if expErr != "" {
				t.Errorf("FAIL: %d: expected error %q", itest, expErr)
				return
			}

			a = strings.Split(rset, "\n")
			for i, v := range a {
				a[i] = strings.TrimSpace(v)
			}
			e := strings.Join(a, "\n")
			if g != e {
				t.Errorf("FAIL: test # %d\n%s\n---- g\n%s\n---- e\n%s\n----", itest, q, g, e)
				return
			}

			return true
		}() && *oFastFail {
			return
		}
	}
	return
}