<commit_before>package prescription_test

import (
	"fmt"
	"time"

	"github.com/globalsign/mgo/bson"
	"syreclabs.com/go/faker"

	"github.com/tidepool-org/platform/structure"
	"github.com/tidepool-org/platform/structure/validator"
	userTest "github.com/tidepool-org/platform/user/test"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/tidepool-org/platform/prescription/test"
	"github.com/tidepool-org/platform/user"

	"github.com/tidepool-org/platform/prescription"
)

var _ = Describe("Prescription", func() {
	Context("With a submitted revision", func() {
		var revisionCreate *prescription.RevisionCreate
		var userID string

		BeforeEach(func() {
			revisionCreate = test.RandomRevisionCreate()
			revisionCreate.State = prescription.StateSubmitted
			userID = user.NewID()
		})

		Context("Create new prescription", func() {
			var prescr *prescription.Prescription

			BeforeEach(func() {
				prescr = prescription.NewPrescription(userID, revisionCreate)
				Expect(prescr).ToNot(BeNil())
			})

			It("creates a non-empty id", func() {
				Expect(prescr.ID).ToNot(BeEmpty())
			})

			It("does not set the patientId", func() {
				Expect(prescr.PatientUserID).To(BeEmpty())
			})

			It("generates a non-empty access code", func() {
				Expect(prescr.AccessCode).ToNot(BeEmpty())
			})

			It("sets the state to the revision state", func() {
				Expect(prescr.State).To(Equal(revisionCreate.State))
			})

			It("sets the latest revision attribute to new revision", func() {
				Expect(prescr.LatestRevision).ToNot(BeNil())
			})

			It("populates the revision history with the newly created revision", func() {
				Expect(prescr.RevisionHistory).ToNot(BeEmpty())
				Expect(prescr.RevisionHistory[0]).To(Equal(prescr.LatestRevision))
			})

			It("sets the created user id correctly", func() {
				Expect(prescr.CreatedUserID).To(Equal(userID))
			})

			It("sets the prescriber user id correctly", func() {
				Expect(prescr.PrescriberUserID).To(Equal(userID))
			})

			It("sets the created time correctly", func() {
				Expect(prescr.CreatedTime).To(BeTemporally("~", time.Now()))
			})

			It("does not set the deleted time", func() {
				Expect(prescr.DeletedTime).To(BeNil())
			})

			It("does not set the deleted user id", func() {
				Expect(prescr.DeletedUserID).To(Equal(""))
			})

			It("creates a revision with id 0", func() {
				Expect(prescr.LatestRevision.RevisionID).To(Equal(0))
			})

			It("sets the modified time", func() {
				Expect(prescr.ModifiedTime).To(BeTemporally("~", time.Now()))
			})

			It("sets the modified time", func() {
				Expect(prescr.ModifiedUserID).To(Equal(userID))
			})
		})
	})

	Describe("Update", func() {
		var revisionCreate *prescription.RevisionCreate
		var usr *user.User

		BeforeEach(func() {
			revisionCreate = test.RandomRevisionCreate()
			revisionCreate.State = prescription.StatePending
			usr = userTest.RandomUser()
		})

		Describe("AddRevision", func() {
			var prescr *prescription.Prescription
			var newRevision *prescription.RevisionCreate
			var update *prescription.Update

			BeforeEach(func() {
				prescr = prescription.NewPrescription(*usr.UserID, revisionCreate)
				newRevision = test.RandomRevisionCreate()
				update = prescription.NewPrescriptionAddRevisionUpdate(usr, prescr, newRevision)
			})

			It("sets the revision correctly", func() {
				expectedRevision := prescription.NewRevision(*usr.UserID, prescr.LatestRevision.RevisionID+1, newRevision)
				expectedRevision.Attributes.CreatedTime = update.Revision.Attributes.CreatedTime
				Expect(*update.Revision).To(Equal(*expectedRevision))
			})

			It("sets the state correctly", func() {
				Expect(update.State).To(Equal(newRevision.State))
			})

			It("sets the prescriber id correctly", func() {
				Expect(update.PrescriberUserID).To(Equal(*usr.UserID))
			})

			It("doesn't set the patient id", func() {
				Expect(update.PatientUserID).To(BeEmpty())
			})

			It("sets the expiration time", func() {
				Expect(*update.ExpirationTime).To(BeTemporally(">", time.Now()))
			})

			It("sets the modified time", func() {
				Expect(update.ModifiedTime).To(BeTemporally("~", time.Now()))
			})

			It("sets the modified user id", func() {
				Expect(update.ModifiedUserID).To(Equal(*usr.UserID))
			})
		})

		Describe("ClaimUpdate", func() {
			var prescr *prescription.Prescription
			var update *prescription.Update

			BeforeEach(func() {
				revisionCreate.State = prescription.StateSubmitted
				prescr = prescription.NewPrescription(*usr.UserID, revisionCreate)
				update = prescription.NewPrescriptionClaimUpdate(usr, prescr)
			})

			It("sets the state to reviewed", func() {
				Expect(update.State).To(Equal(prescription.StateReviewed))
			})

			It("sets the patient id correctly", func() {
				Expect(update.PatientUserID).To(Equal(*usr.UserID))
			})

			It("doesn't set the prescriber id", func() {
				Expect(update.PrescriberUserID).To(BeEmpty())
			})

			It("resets the expiration time", func() {
				Expect(update.ExpirationTime).To(BeNil())
			})

			It("sets the modified time", func() {
				Expect(update.ModifiedTime).To(BeTemporally("~", time.Now()))
			})

			It("sets the modified user id", func() {
				Expect(update.ModifiedUserID).To(Equal(*usr.UserID))
			})
		})

		Describe("StateUpdate", func() {
			var prescr *prescription.Prescription
			var update *prescription.Update

			BeforeEach(func() {
				revisionCreate.State = prescription.StateReviewed
				prescr = prescription.NewPrescription(*usr.UserID, revisionCreate)
				stateUpdate := prescription.NewStateUpdate()
				stateUpdate.State = prescription.StateActive
				update = prescription.NewPrescriptionStateUpdate(usr, prescr, stateUpdate)
			})

			It("doesn't create a new revision", func() {
				Expect(update.Revision).To(BeNil())
			})

			It("sets the state to reviewed", func() {
				Expect(update.State).To(Equal(prescription.StateActive))
			})

			It("doesn't set a patient id", func() {
				Expect(update.PatientUserID).To(BeEmpty())
			})

			It("doesn't set the prescriber id", func() {
				Expect(update.PrescriberUserID).To(BeEmpty())
			})

			It("resets the expiration time", func() {
				Expect(update.ExpirationTime).To(BeNil())
			})

			It("sets the modified time", func() {
				Expect(update.ModifiedTime).To(BeTemporally("~", time.Now()))
			})

			It("sets the modified user id", func() {
				Expect(update.ModifiedUserID).To(Equal(*usr.UserID))
			})
		})
	})

	Describe("Filter", func() {
		Describe("Validate", func() {
			When("current user is NOT a clinician", func() {
				var usr *user.User
				var filter *prescription.Filter
				var validate structure.Validator

				BeforeEach(func() {
					usr = userTest.RandomUser()
					usr.Roles = &[]string{}

					var err error
					filter, err = prescription.NewFilter(usr)
					Expect(err).ToNot(HaveOccurred())

					validate = validator.New()
					Expect(validate.Validate(filter)).ToNot(HaveOccurred())
				})

				It("fails when patient id is not same as current user id", func() {
					patientID := userTest.RandomID()
					Expect(patientID).ToNot(Equal(filter.PatientUserID))
					filter.PatientUserID = patientID

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the state is draft", func() {
					filter.State = prescription.StateDraft

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the state is pending", func() {
					filter.State = prescription.StatePending

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the state is expired", func() {
					filter.State = prescription.StateExpired

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when the state is submitted", func() {
					filter.State = prescription.StateSubmitted

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is active", func() {
					filter.State = prescription.StateActive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is inactive", func() {
					filter.State = prescription.StateInactive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is reviewed", func() {
					filter.State = prescription.StateReviewed

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the state is unrecognized", func() {
					filter.State = "invalid"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when patient email is set", func() {
					filter.PatientEmail = faker.Internet().Email()

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail with a valid id", func() {
					filter.ID = bson.NewObjectId().Hex()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the id is 13 hex characters", func() {
					filter.ID = fmt.Sprintf("%sa", bson.NewObjectId().Hex())

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the id contains non-hex character", func() {
					filter.ID = "507f1f77bcf86cd799439011z"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})
			})

			When("current user is a clinician", func() {
				var usr *user.User
				var filter *prescription.Filter
				var validate structure.Validator

				BeforeEach(func() {
					usr = userTest.RandomUser()
					usr.Roles = &[]string{user.RoleClinic}

					var err error
					filter, err = prescription.NewFilter(usr)
					Expect(err).ToNot(HaveOccurred())

					validate = validator.New()
					Expect(validate.Validate(filter)).ToNot(HaveOccurred())
				})

				It("fails when patient id is invalid", func() {
					filter.PatientUserID = "invalid"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when patient id invalid", func() {
					filter.PatientUserID = userTest.RandomID()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is draft", func() {
					filter.State = prescription.StateDraft

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is pending", func() {
					filter.State = prescription.StatePending

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is expired", func() {
					filter.State = prescription.StateExpired

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is submitted", func() {
					filter.State = prescription.StateSubmitted

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is active", func() {
					filter.State = prescription.StateActive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is inactive", func() {
					filter.State = prescription.StateInactive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is reviewed", func() {
					filter.State = prescription.StateReviewed

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the state is unrecognized", func() {
					filter.State = "invalid"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when patient email is valid", func() {
					filter.PatientEmail = faker.Internet().Email()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when patient email is invalid", func() {
					filter.PatientEmail = "invalid-email.com"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when the patient email is valid", func() {
					filter.PatientEmail = faker.Internet().Email()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail with a valid id", func() {
					filter.ID = bson.NewObjectId().Hex()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the id is 13 hex characters", func() {
					filter.ID = fmt.Sprintf("%sa", bson.NewObjectId().Hex())

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the id contains non-hex character", func() {
					filter.ID = "507f1f77bcf86cd799439011z"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})
			})
		})
	})
})
<commit_msg>Fix flaky test<commit_after>package prescription_test

import (
	"fmt"
	"time"

	"github.com/globalsign/mgo/bson"
	"syreclabs.com/go/faker"

	"github.com/tidepool-org/platform/structure"
	"github.com/tidepool-org/platform/structure/validator"
	userTest "github.com/tidepool-org/platform/user/test"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/tidepool-org/platform/prescription/test"
	"github.com/tidepool-org/platform/user"

	"github.com/tidepool-org/platform/prescription"
)

var _ = Describe("Prescription", func() {
	Context("With a submitted revision", func() {
		var revisionCreate *prescription.RevisionCreate
		var userID string

		BeforeEach(func() {
			revisionCreate = test.RandomRevisionCreate()
			revisionCreate.State = prescription.StateSubmitted
			userID = user.NewID()
		})

		Context("Create new prescription", func() {
			var prescr *prescription.Prescription

			BeforeEach(func() {
				prescr = prescription.NewPrescription(userID, revisionCreate)
				Expect(prescr).ToNot(BeNil())
			})

			It("creates a non-empty id", func() {
				Expect(prescr.ID).ToNot(BeEmpty())
			})

			It("does not set the patientId", func() {
				Expect(prescr.PatientUserID).To(BeEmpty())
			})

			It("generates a non-empty access code", func() {
				Expect(prescr.AccessCode).ToNot(BeEmpty())
			})

			It("sets the state to the revision state", func() {
				Expect(prescr.State).To(Equal(revisionCreate.State))
			})

			It("sets the latest revision attribute to new revision", func() {
				Expect(prescr.LatestRevision).ToNot(BeNil())
			})

			It("populates the revision history with the newly created revision", func() {
				Expect(prescr.RevisionHistory).ToNot(BeEmpty())
				Expect(prescr.RevisionHistory[0]).To(Equal(prescr.LatestRevision))
			})

			It("sets the created user id correctly", func() {
				Expect(prescr.CreatedUserID).To(Equal(userID))
			})

			It("sets the prescriber user id correctly", func() {
				Expect(prescr.PrescriberUserID).To(Equal(userID))
			})

			It("sets the created time correctly", func() {
				Expect(prescr.CreatedTime).To(BeTemporally("~", time.Now()))
			})

			It("does not set the deleted time", func() {
				Expect(prescr.DeletedTime).To(BeNil())
			})

			It("does not set the deleted user id", func() {
				Expect(prescr.DeletedUserID).To(Equal(""))
			})

			It("creates a revision with id 0", func() {
				Expect(prescr.LatestRevision.RevisionID).To(Equal(0))
			})

			It("sets the modified time", func() {
				Expect(prescr.ModifiedTime).To(BeTemporally("~", time.Now()))
			})

			It("sets the modified time", func() {
				Expect(prescr.ModifiedUserID).To(Equal(userID))
			})
		})
	})

	Describe("Update", func() {
		var revisionCreate *prescription.RevisionCreate
		var usr *user.User

		BeforeEach(func() {
			revisionCreate = test.RandomRevisionCreate()
			revisionCreate.State = prescription.StatePending
			usr = userTest.RandomUser()
		})

		Describe("AddRevision", func() {
			var prescr *prescription.Prescription
			var newRevision *prescription.RevisionCreate
			var update *prescription.Update

			BeforeEach(func() {
				prescr = prescription.NewPrescription(*usr.UserID, revisionCreate)
				newRevision = test.RandomRevisionCreate()
				update = prescription.NewPrescriptionAddRevisionUpdate(usr, prescr, newRevision)
			})

			It("sets the revision correctly", func() {
				expectedRevision := prescription.NewRevision(*usr.UserID, prescr.LatestRevision.RevisionID+1, newRevision)
				expectedRevision.Attributes.CreatedTime = update.Revision.Attributes.CreatedTime
				Expect(*update.Revision).To(Equal(*expectedRevision))
			})

			It("sets the state correctly", func() {
				Expect(update.State).To(Equal(newRevision.State))
			})

			It("sets the prescriber id correctly", func() {
				Expect(update.PrescriberUserID).To(Equal(*usr.UserID))
			})

			It("doesn't set the patient id", func() {
				Expect(update.PatientUserID).To(BeEmpty())
			})

			It("sets the expiration time", func() {
				Expect(*update.ExpirationTime).To(BeTemporally(">", time.Now()))
			})

			It("sets the modified time", func() {
				Expect(update.ModifiedTime).To(BeTemporally("~", time.Now(), 10*time.Millisecond))
			})

			It("sets the modified user id", func() {
				Expect(update.ModifiedUserID).To(Equal(*usr.UserID))
			})
		})

		Describe("ClaimUpdate", func() {
			var prescr *prescription.Prescription
			var update *prescription.Update

			BeforeEach(func() {
				revisionCreate.State = prescription.StateSubmitted
				prescr = prescription.NewPrescription(*usr.UserID, revisionCreate)
				update = prescription.NewPrescriptionClaimUpdate(usr, prescr)
			})

			It("sets the state to reviewed", func() {
				Expect(update.State).To(Equal(prescription.StateReviewed))
			})

			It("sets the patient id correctly", func() {
				Expect(update.PatientUserID).To(Equal(*usr.UserID))
			})

			It("doesn't set the prescriber id", func() {
				Expect(update.PrescriberUserID).To(BeEmpty())
			})

			It("resets the expiration time", func() {
				Expect(update.ExpirationTime).To(BeNil())
			})

			It("sets the modified time", func() {
				Expect(update.ModifiedTime).To(BeTemporally("~", time.Now()))
			})

			It("sets the modified user id", func() {
				Expect(update.ModifiedUserID).To(Equal(*usr.UserID))
			})
		})

		Describe("StateUpdate", func() {
			var prescr *prescription.Prescription
			var update *prescription.Update

			BeforeEach(func() {
				revisionCreate.State = prescription.StateReviewed
				prescr = prescription.NewPrescription(*usr.UserID, revisionCreate)
				stateUpdate := prescription.NewStateUpdate()
				stateUpdate.State = prescription.StateActive
				update = prescription.NewPrescriptionStateUpdate(usr, prescr, stateUpdate)
			})

			It("doesn't create a new revision", func() {
				Expect(update.Revision).To(BeNil())
			})

			It("sets the state to reviewed", func() {
				Expect(update.State).To(Equal(prescription.StateActive))
			})

			It("doesn't set a patient id", func() {
				Expect(update.PatientUserID).To(BeEmpty())
			})

			It("doesn't set the prescriber id", func() {
				Expect(update.PrescriberUserID).To(BeEmpty())
			})

			It("resets the expiration time", func() {
				Expect(update.ExpirationTime).To(BeNil())
			})

			It("sets the modified time", func() {
				Expect(update.ModifiedTime).To(BeTemporally("~", time.Now()))
			})

			It("sets the modified user id", func() {
				Expect(update.ModifiedUserID).To(Equal(*usr.UserID))
			})
		})
	})

	Describe("Filter", func() {
		Describe("Validate", func() {
			When("current user is NOT a clinician", func() {
				var usr *user.User
				var filter *prescription.Filter
				var validate structure.Validator

				BeforeEach(func() {
					usr = userTest.RandomUser()
					usr.Roles = &[]string{}

					var err error
					filter, err = prescription.NewFilter(usr)
					Expect(err).ToNot(HaveOccurred())

					validate = validator.New()
					Expect(validate.Validate(filter)).ToNot(HaveOccurred())
				})

				It("fails when patient id is not same as current user id", func() {
					patientID := userTest.RandomID()
					Expect(patientID).ToNot(Equal(filter.PatientUserID))
					filter.PatientUserID = patientID

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the state is draft", func() {
					filter.State = prescription.StateDraft

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the state is pending", func() {
					filter.State = prescription.StatePending

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the state is expired", func() {
					filter.State = prescription.StateExpired

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when the state is submitted", func() {
					filter.State = prescription.StateSubmitted

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is active", func() {
					filter.State = prescription.StateActive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is inactive", func() {
					filter.State = prescription.StateInactive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is reviewed", func() {
					filter.State = prescription.StateReviewed

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the state is unrecognized", func() {
					filter.State = "invalid"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when patient email is set", func() {
					filter.PatientEmail = faker.Internet().Email()

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail with a valid id", func() {
					filter.ID = bson.NewObjectId().Hex()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the id is 13 hex characters", func() {
					filter.ID = fmt.Sprintf("%sa", bson.NewObjectId().Hex())

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the id contains non-hex character", func() {
					filter.ID = "507f1f77bcf86cd799439011z"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})
			})

			When("current user is a clinician", func() {
				var usr *user.User
				var filter *prescription.Filter
				var validate structure.Validator

				BeforeEach(func() {
					usr = userTest.RandomUser()
					usr.Roles = &[]string{user.RoleClinic}

					var err error
					filter, err = prescription.NewFilter(usr)
					Expect(err).ToNot(HaveOccurred())

					validate = validator.New()
					Expect(validate.Validate(filter)).ToNot(HaveOccurred())
				})

				It("fails when patient id is invalid", func() {
					filter.PatientUserID = "invalid"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when patient id invalid", func() {
					filter.PatientUserID = userTest.RandomID()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is draft", func() {
					filter.State = prescription.StateDraft

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is pending", func() {
					filter.State = prescription.StatePending

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is expired", func() {
					filter.State = prescription.StateExpired

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is submitted", func() {
					filter.State = prescription.StateSubmitted

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is active", func() {
					filter.State = prescription.StateActive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is inactive", func() {
					filter.State = prescription.StateInactive

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail when the state is reviewed", func() {
					filter.State = prescription.StateReviewed

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the state is unrecognized", func() {
					filter.State = "invalid"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when patient email is valid", func() {
					filter.PatientEmail = faker.Internet().Email()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when patient email is invalid", func() {
					filter.PatientEmail = "invalid-email.com"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("doesn't fail when the patient email is valid", func() {
					filter.PatientEmail = faker.Internet().Email()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("doesn't fail with a valid id", func() {
					filter.ID = bson.NewObjectId().Hex()

					filter.Validate(validate)
					Expect(validate.Error()).ToNot(HaveOccurred())
				})

				It("fails when the id is 13 hex characters", func() {
					filter.ID = fmt.Sprintf("%sa", bson.NewObjectId().Hex())

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})

				It("fails when the id contains non-hex character", func() {
					filter.ID = "507f1f77bcf86cd799439011z"

					filter.Validate(validate)
					Expect(validate.Error()).To(HaveOccurred())
				})
			})
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"gopkg.in/oleiade/reflections.v1"
	"strconv"
	"strings"
)

type UwsgiStatsCollector struct {
	Reader           *UwsgiStatsReader
	ReadsDesc        *prometheus.Desc
	ErrorDesc        *prometheus.Desc
	UwsgiStats       []Stat
	UwsgiSocketStats []Stat
	UwsgiWorkerStats []Stat
	UwsgiAppStats    []Stat
	UwsgiCoreStats   []Stat
}

type Stat struct {
	Name           string
	PrometheusType prometheus.ValueType
	Desc           *prometheus.Desc
}

func (u *UwsgiStatsCollector) GatherUwsgiStats() *[]UwsgiStatsReadResults {
	uwsgi_stats_results := read_uwsgi_stats(u.Reader)
	return uwsgi_stats_results
}

func (u *UwsgiStatsCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- u.ReadsDesc
	ch <- u.ErrorDesc
	for _, stat := range u.UwsgiStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiSocketStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiWorkerStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiAppStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiCoreStats {
		ch <- stat.Desc
	}
}

func NewStatMetric(stat *Stat, value int, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Address,
		results.Identifier,
	)
}

func NewSocketStatMetric(stat *Stat, value int, socket *UwsgiSocket, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Address,
		results.Identifier,
		socket.Name,
		socket.Proto,
	)
}

func NewWorkerStatMetric(stat *Stat, value int, worker *UwsgiWorker, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Address,
		results.Identifier,
		strconv.Itoa(worker.Id),
		worker.Status,
	)
}

func NewAppStatMetric(stat *Stat, value int, app *UwsgiApp, worker *UwsgiWorker, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Address,
		results.Identifier,
		strconv.Itoa(worker.Id),
		worker.Status,
		strconv.Itoa(app.Id),
		app.Mountpoint,
		app.Chdir,
	)
}

func NewCoreStatMetric(stat *Stat, value int, core *UwsgiCore, worker *UwsgiWorker, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Address,
		results.Identifier,
		strconv.Itoa(worker.Id),
		worker.Status,
		strconv.Itoa(core.Id),
	)
}

func (u *UwsgiStatsCollector) Collect(ch chan<- prometheus.Metric) {
	uwsgi_stats_results := u.GatherUwsgiStats()
	for _, results := range *uwsgi_stats_results {
		if results.Error != nil {
			ch <- prometheus.MustNewConstMetric(
				u.ErrorDesc,
				prometheus.CounterValue,
				float64(1),
				results.Type,
				results.Address,
				results.Identifier,
			)
			continue
		}
		ch <- prometheus.MustNewConstMetric(
			u.ReadsDesc,
			prometheus.CounterValue,
			float64(1),
			results.Type,
			results.Address,
			results.Identifier,
			results.UwsgiStats.Version,
		)
		for _, stat := range u.UwsgiStats {
			value, err := reflections.GetField(results.UwsgiStats, stat.Name)
			if err != nil {
				panic(err)
			}
			ch <- NewStatMetric(&stat, value.(int), &results)
		}
		for _, stat := range u.UwsgiSocketStats {
			for _, uwsgi_socket := range results.UwsgiStats.Sockets {
				value, err := reflections.GetField(uwsgi_socket, stat.Name)
				if err != nil {
					panic(err)
				}
				ch <- NewSocketStatMetric(&stat, value.(int), &uwsgi_socket, &results)
			}
		}
		for _, stat := range u.UwsgiWorkerStats {
			for _, uwsgi_worker := range results.UwsgiStats.Workers {
				value, err := reflections.GetField(uwsgi_worker, stat.Name)
				if err != nil {
					panic(err)
				}
				ch <- NewWorkerStatMetric(&stat, value.(int), &uwsgi_worker, &results)
			}
		}
		for _, stat := range u.UwsgiAppStats {
			for _, worker := range results.UwsgiStats.Workers {
				for _, app := range worker.Apps {
					value, err := reflections.GetField(app, stat.Name)
					if err != nil {
						panic(err)
					}
					ch <- NewAppStatMetric(&stat, value.(int), &app, &worker, &results)
				}
			}
		}
		for _, stat := range u.UwsgiCoreStats {
			for _, worker := range results.UwsgiStats.Workers {
				for _, core := range worker.Cores {
					value, err := reflections.GetField(core, stat.Name)
					if err != nil {
						panic(err)
					}
					ch <- NewCoreStatMetric(&stat, value.(int), &core, &worker, &results)
				}
			}
		}
	}
}

func NewUwsgiGaugeStat(name string, description string, prefix string, label_names *[]string) Stat {
	prometheus_name := prefix + strings.ToLower(name)
	return Stat{
		name,
		prometheus.GaugeValue,
		prometheus.NewDesc(
			prometheus_name,
			description,
			*label_names,
			prometheus.Labels{},
		),
	}
}

func NewUwsgiCounterStat(name string, description string, prefix string, suffix string, label_names *[]string) Stat {
	prometheus_name := prefix + strings.ToLower(name) + suffix
	return Stat{
		name,
		prometheus.CounterValue,
		prometheus.NewDesc(
			prometheus_name,
			description,
			*label_names,
			prometheus.Labels{},
		),
	}
}

func NewUwsgiStats() []Stat {
	prefix := "uwsgi_stats_"
	label_names := []string{"type", "uwsgi_stats_address", "identifier"}
	return []Stat{
		NewUwsgiGaugeStat("Listen_Queue", "Length of listen queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Listen_Queue_Errors", "Number of listen queue errors.", prefix, &label_names),
		NewUwsgiGaugeStat("Signal_Queue", "Length of signal queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Load", "Load.", prefix, &label_names),
	}
}

func NewUwsgiSocketStats() []Stat {
	prefix := "uwsgi_stats_socket_"
	label_names := []string{"type", "uwsgi_stats_address", "identifier", "name", "proto"}
	return []Stat{
		NewUwsgiGaugeStat("Queue", "Length of socket queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Max_Queue", "Make length of socket queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Shared", "Shared.", prefix, &label_names),
		NewUwsgiGaugeStat("Can_Offload", "Can socket offload?", prefix, &label_names),
	}
}

func NewUwsgiWorkerStats() []Stat {
	prefix := "uwsgi_stats_worker_"
	suffix := "_total"
	label_names := []string{"type", "uwsgi_stats_address", "identifier", "worker_id", "status"}
	return []Stat{
		NewUwsgiGaugeStat("Accepting", "Is this worker accepting requests?.", prefix, &label_names),
		NewUwsgiCounterStat("Requests", "Number of requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Delta_Requests", "Number of delta requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Exceptions", "Number of exceptions.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Harakiri_Count", "Number of harakiri attempts.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Signals", "Number of signals.", prefix, suffix, &label_names),
		NewUwsgiGaugeStat("Signal_Queue", "Length of signal queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Rss", "Worker RSS bytes.", prefix, &label_names),
		NewUwsgiGaugeStat("Vsz", "Worker VSZ bytes.", prefix, &label_names),
		NewUwsgiGaugeStat("Running_Time", "Worker running time.", prefix, &label_names),
		NewUwsgiGaugeStat("Last_Spawn", "Last worker respawn time.", prefix, &label_names),
		NewUwsgiCounterStat("Respawn_Count", "Worker respawn count.", prefix, suffix, &label_names),
		NewUwsgiGaugeStat("Tx", "Worker transmitted bytes.", prefix, &label_names),
		NewUwsgiGaugeStat("Avg_Rt", "Worker average RT.", prefix, &label_names),
	}
}

func NewUwsgiAppStats() []Stat {
	prefix := "uwsgi_stats_worker_app_"
	suffix := "_total"
	label_names := []string{"type", "uwsgi_stats_address", "identifier", "worker_id", "status", "app_id", "mountpoint", "chdir"}
	return []Stat{
		NewUwsgiGaugeStat("Startup_Time", "How long this app took to start.", prefix, &label_names),
		NewUwsgiCounterStat("Requests", "Number of requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Exceptions", "Number of exceptions.", prefix, suffix, &label_names),
	}
}

func NewUwsgiCoreStats() []Stat {
	prefix := "uwsgi_stats_worker_core_"
	suffix := "_total"
	label_names := []string{"type", "uwsgi_stats_address", "identifier", "worker_id", "status", "core_id"}
	return []Stat{
		NewUwsgiCounterStat("Requests", "Number of requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Static_Requests", "Number of static requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Routed_Requets", "Number of routed requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Ofloaded_Requests", "Number of requests offloaded to threads.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Write_Errors", "Number of write errors.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Read_Errors", "Number of read errors.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("In_Requests", "Number of requests in.", prefix, suffix, &label_names),
	}
}

func NewUwsgiStatsCollector(reader *UwsgiStatsReader) *UwsgiStatsCollector {

	return &UwsgiStatsCollector{
		Reader: reader,
		ReadsDesc: prometheus.NewDesc(
			"uwsgi_stats_scrapes_total",
			"Number of times stats are scraped",
			[]string{"type", "uwsgi_stats_address", "identifier", "uwsgi_version"},
			prometheus.Labels{},
		),
		ErrorDesc: prometheus.NewDesc(
			"uwsgi_stats_read_error_total",
			"Problems reading stats",
			[]string{"type", "uwsgi_stats_address", "identifier"},
			prometheus.Labels{},
		),
		UwsgiStats:       NewUwsgiStats(),
		UwsgiSocketStats: NewUwsgiSocketStats(),
		UwsgiWorkerStats: NewUwsgiWorkerStats(),
		UwsgiAppStats:    NewUwsgiAppStats(),
		UwsgiCoreStats:   NewUwsgiCoreStats(),
	}
}
<commit_msg>Remove address from metric labels, long and unused<commit_after>package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"gopkg.in/oleiade/reflections.v1"
	"strconv"
	"strings"
)

type UwsgiStatsCollector struct {
	Reader           *UwsgiStatsReader
	ReadsDesc        *prometheus.Desc
	ErrorDesc        *prometheus.Desc
	UwsgiStats       []Stat
	UwsgiSocketStats []Stat
	UwsgiWorkerStats []Stat
	UwsgiAppStats    []Stat
	UwsgiCoreStats   []Stat
}

type Stat struct {
	Name           string
	PrometheusType prometheus.ValueType
	Desc           *prometheus.Desc
}

func (u *UwsgiStatsCollector) GatherUwsgiStats() *[]UwsgiStatsReadResults {
	uwsgi_stats_results := read_uwsgi_stats(u.Reader)
	return uwsgi_stats_results
}

func (u *UwsgiStatsCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- u.ReadsDesc
	ch <- u.ErrorDesc
	for _, stat := range u.UwsgiStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiSocketStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiWorkerStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiAppStats {
		ch <- stat.Desc
	}
	for _, stat := range u.UwsgiCoreStats {
		ch <- stat.Desc
	}
}

func NewStatMetric(stat *Stat, value int, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Identifier,
	)
}

func NewSocketStatMetric(stat *Stat, value int, socket *UwsgiSocket, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Identifier,
		socket.Name,
		socket.Proto,
	)
}

func NewWorkerStatMetric(stat *Stat, value int, worker *UwsgiWorker, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Identifier,
		strconv.Itoa(worker.Id),
		worker.Status,
	)
}

func NewAppStatMetric(stat *Stat, value int, app *UwsgiApp, worker *UwsgiWorker, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Identifier,
		strconv.Itoa(worker.Id),
		worker.Status,
		strconv.Itoa(app.Id),
		app.Mountpoint,
		app.Chdir,
	)
}

func NewCoreStatMetric(stat *Stat, value int, core *UwsgiCore, worker *UwsgiWorker, results *UwsgiStatsReadResults) prometheus.Metric {
	return prometheus.MustNewConstMetric(
		stat.Desc,
		stat.PrometheusType,
		float64(value),
		results.Type,
		results.Identifier,
		strconv.Itoa(worker.Id),
		worker.Status,
		strconv.Itoa(core.Id),
	)
}

func (u *UwsgiStatsCollector) Collect(ch chan<- prometheus.Metric) {
	uwsgi_stats_results := u.GatherUwsgiStats()
	for _, results := range *uwsgi_stats_results {
		if results.Error != nil {
			ch <- prometheus.MustNewConstMetric(
				u.ErrorDesc,
				prometheus.CounterValue,
				float64(1),
				results.Type,
				results.Identifier,
			)
			continue
		}
		ch <- prometheus.MustNewConstMetric(
			u.ReadsDesc,
			prometheus.CounterValue,
			float64(1),
			results.Type,
			results.Identifier,
			results.UwsgiStats.Version,
		)
		for _, stat := range u.UwsgiStats {
			value, err := reflections.GetField(results.UwsgiStats, stat.Name)
			if err != nil {
				panic(err)
			}
			ch <- NewStatMetric(&stat, value.(int), &results)
		}
		for _, stat := range u.UwsgiSocketStats {
			for _, uwsgi_socket := range results.UwsgiStats.Sockets {
				value, err := reflections.GetField(uwsgi_socket, stat.Name)
				if err != nil {
					panic(err)
				}
				ch <- NewSocketStatMetric(&stat, value.(int), &uwsgi_socket, &results)
			}
		}
		for _, stat := range u.UwsgiWorkerStats {
			for _, uwsgi_worker := range results.UwsgiStats.Workers {
				value, err := reflections.GetField(uwsgi_worker, stat.Name)
				if err != nil {
					panic(err)
				}
				ch <- NewWorkerStatMetric(&stat, value.(int), &uwsgi_worker, &results)
			}
		}
		for _, stat := range u.UwsgiAppStats {
			for _, worker := range results.UwsgiStats.Workers {
				for _, app := range worker.Apps {
					value, err := reflections.GetField(app, stat.Name)
					if err != nil {
						panic(err)
					}
					ch <- NewAppStatMetric(&stat, value.(int), &app, &worker, &results)
				}
			}
		}
		for _, stat := range u.UwsgiCoreStats {
			for _, worker := range results.UwsgiStats.Workers {
				for _, core := range worker.Cores {
					value, err := reflections.GetField(core, stat.Name)
					if err != nil {
						panic(err)
					}
					ch <- NewCoreStatMetric(&stat, value.(int), &core, &worker, &results)
				}
			}
		}
	}
}

func NewUwsgiGaugeStat(name string, description string, prefix string, label_names *[]string) Stat {
	prometheus_name := prefix + strings.ToLower(name)
	return Stat{
		name,
		prometheus.GaugeValue,
		prometheus.NewDesc(
			prometheus_name,
			description,
			*label_names,
			prometheus.Labels{},
		),
	}
}

func NewUwsgiCounterStat(name string, description string, prefix string, suffix string, label_names *[]string) Stat {
	prometheus_name := prefix + strings.ToLower(name) + suffix
	return Stat{
		name,
		prometheus.CounterValue,
		prometheus.NewDesc(
			prometheus_name,
			description,
			*label_names,
			prometheus.Labels{},
		),
	}
}

func NewUwsgiStats() []Stat {
	prefix := "uwsgi_stats_"
	label_names := []string{"type", "identifier"}
	return []Stat{
		NewUwsgiGaugeStat("Listen_Queue", "Length of listen queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Listen_Queue_Errors", "Number of listen queue errors.", prefix, &label_names),
		NewUwsgiGaugeStat("Signal_Queue", "Length of signal queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Load", "Load.", prefix, &label_names),
	}
}

func NewUwsgiSocketStats() []Stat {
	prefix := "uwsgi_stats_socket_"
	label_names := []string{"type", "identifier", "name", "proto"}
	return []Stat{
		NewUwsgiGaugeStat("Queue", "Length of socket queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Max_Queue", "Make length of socket queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Shared", "Shared.", prefix, &label_names),
		NewUwsgiGaugeStat("Can_Offload", "Can socket offload?", prefix, &label_names),
	}
}

func NewUwsgiWorkerStats() []Stat {
	prefix := "uwsgi_stats_worker_"
	suffix := "_total"
	label_names := []string{"type", "identifier", "worker_id", "status"}
	return []Stat{
		NewUwsgiGaugeStat("Accepting", "Is this worker accepting requests?.", prefix, &label_names),
		NewUwsgiCounterStat("Requests", "Number of requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Delta_Requests", "Number of delta requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Exceptions", "Number of exceptions.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Harakiri_Count", "Number of harakiri attempts.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Signals", "Number of signals.", prefix, suffix, &label_names),
		NewUwsgiGaugeStat("Signal_Queue", "Length of signal queue.", prefix, &label_names),
		NewUwsgiGaugeStat("Rss", "Worker RSS bytes.", prefix, &label_names),
		NewUwsgiGaugeStat("Vsz", "Worker VSZ bytes.", prefix, &label_names),
		NewUwsgiGaugeStat("Running_Time", "Worker running time.", prefix, &label_names),
		NewUwsgiGaugeStat("Last_Spawn", "Last worker respawn time.", prefix, &label_names),
		NewUwsgiCounterStat("Respawn_Count", "Worker respawn count.", prefix, suffix, &label_names),
		NewUwsgiGaugeStat("Tx", "Worker transmitted bytes.", prefix, &label_names),
		NewUwsgiGaugeStat("Avg_Rt", "Worker average RT.", prefix, &label_names),
	}
}

func NewUwsgiAppStats() []Stat {
	prefix := "uwsgi_stats_worker_app_"
	suffix := "_total"
	label_names := []string{"type", "identifier", "worker_id", "status", "app_id", "mountpoint", "chdir"}
	return []Stat{
		NewUwsgiGaugeStat("Startup_Time", "How long this app took to start.", prefix, &label_names),
		NewUwsgiCounterStat("Requests", "Number of requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Exceptions", "Number of exceptions.", prefix, suffix, &label_names),
	}
}

func NewUwsgiCoreStats() []Stat {
	prefix := "uwsgi_stats_worker_core_"
	suffix := "_total"
	label_names := []string{"type", "identifier", "worker_id", "status", "core_id"}
	return []Stat{
		NewUwsgiCounterStat("Requests", "Number of requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Static_Requests", "Number of static requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Routed_Requets", "Number of routed requests.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Ofloaded_Requests", "Number of requests offloaded to threads.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Write_Errors", "Number of write errors.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("Read_Errors", "Number of read errors.", prefix, suffix, &label_names),
		NewUwsgiCounterStat("In_Requests", "Number of requests in.", prefix, suffix, &label_names),
	}
}

func NewUwsgiStatsCollector(reader *UwsgiStatsReader) *UwsgiStatsCollector {

	return &UwsgiStatsCollector{
		Reader: reader,
		ReadsDesc: prometheus.NewDesc(
			"uwsgi_stats_scrapes_total",
			"Number of times stats are scraped",
			[]string{"type", "identifier", "uwsgi_version"},
			prometheus.Labels{},
		),
		ErrorDesc: prometheus.NewDesc(
			"uwsgi_stats_read_error_total",
			"Problems reading stats",
			[]string{"type", "identifier"},
			prometheus.Labels{},
		),
		UwsgiStats:       NewUwsgiStats(),
		UwsgiSocketStats: NewUwsgiSocketStats(),
		UwsgiWorkerStats: NewUwsgiWorkerStats(),
		UwsgiAppStats:    NewUwsgiAppStats(),
		UwsgiCoreStats:   NewUwsgiCoreStats(),
	}
}
<|endoftext|>


<commit_before>package connection

import (
	"github.com/deweysasser/locksmith/data"
	"github.com/deweysasser/locksmith/output"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
	"time"
)

type FileConnection struct {
	Type string
	Path string
}

func (c *FileConnection) String() string {
	return "file://" + c.Path
}

func (c *FileConnection) Fetch() (keys <- chan data.Key, accounts <- chan data.Account) {
	fKeys := data.NewFanInKey(nil)
	defer fKeys.DoneAdding()
	keys = fKeys.Output()

	cAccounts := make(chan data.Account)
	defer close(cAccounts)

	path := c.Path

	fetchPath(path, fKeys)
	return keys, cAccounts
}

func fetchPath(path string, inKeys *data.FanInKeys) {
	info, err := os.Stat(path)
	if err != nil {
		return
	}

	if info.IsDir() {
		files, err := ioutil.ReadDir(path)
		if err == nil {
			for _, file := range files {
				if !shouldSkipFile(file) {
					fetchPath(path+"/"+file.Name(), inKeys)
				}
			}
		}
	} else {
		inKeys.Add(fetchFile(path))
	}
}

func shouldSkipFile(info os.FileInfo) bool {
	switch {
	case matches("~$", info.Name()):
		return true
	case matches("^#.*", info.Name()):
		return true
	default:
		return false
	}
}

func matches(re, name string) bool {
	m, _ := regexp.Match(re, []byte(name))
	return m
}

func fetchFile(path string) chan data.Key {
	keys := make(chan data.Key)
	go func() {
		defer close(keys)
		output.Debug("Reading", path)

		if info, err := os.Stat(path); err == nil {
			bytes, err := ioutil.ReadFile(path)
			if err != nil {
				return
			}

			s := string(bytes)

			switch {
			case strings.Contains(s, "aws_access_key_id"):
				data.ParseAWSCredentials(bytes, keys)
			default:
				readSSHKey(bytes, keys, info.ModTime(), basename(path))
			}
		}else {
			output.Error("Failed to read", path)
		}
	}()
	return keys
}

func basename(path string) string {
	if i := strings.LastIndex(path, "/"); i > 0 {
		i++
		return path[i:]
	} else {
		return path
	}
}

func readSSHKey(bytes []byte, keys chan data.Key, time time.Time, names ...string) {
	k := data.NewKey(string(bytes), time, names...)
	if k != nil {
		keys <- k
	}
}

func (c *FileConnection) Id() data.ID {
	return data.IdFromString(c.Path)
}
<commit_msg>Skip known hosts files<commit_after>package connection

import (
	"github.com/deweysasser/locksmith/data"
	"github.com/deweysasser/locksmith/output"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
	"time"
)

type FileConnection struct {
	Type string
	Path string
}

func (c *FileConnection) String() string {
	return "file://" + c.Path
}

func (c *FileConnection) Fetch() (keys <- chan data.Key, accounts <- chan data.Account) {
	fKeys := data.NewFanInKey(nil)
	defer fKeys.DoneAdding()
	keys = fKeys.Output()

	cAccounts := make(chan data.Account)
	defer close(cAccounts)

	path := c.Path

	fetchPath(path, fKeys)
	return keys, cAccounts
}

func fetchPath(path string, inKeys *data.FanInKeys) {
	info, err := os.Stat(path)
	if err != nil {
		return
	}

	if info.IsDir() {
		files, err := ioutil.ReadDir(path)
		if err == nil {
			for _, file := range files {
				if !shouldSkipFile(file) {
					fetchPath(path+"/"+file.Name(), inKeys)
				}
			}
		}
	} else {
		inKeys.Add(fetchFile(path))
	}
}

func shouldSkipFile(info os.FileInfo) bool {
	switch {
	case matches("~$", info.Name()):
		return true
	case matches("^#.*", info.Name()):
		return true
	default:
		return false
	}
}

func matches(re, name string) bool {
	m, _ := regexp.Match(re, []byte(name))
	return m
}

func fetchFile(path string) chan data.Key {
	keys := make(chan data.Key)
	go func() {
		defer close(keys)
		output.Debug("Reading", path)

		if info, err := os.Stat(path); err == nil {
			bytes, err := ioutil.ReadFile(path)
			if err != nil {
				return
			}

			s := string(bytes)

			switch {
			case strings.Contains(s, "aws_access_key_id"):
				data.ParseAWSCredentials(bytes, keys)
			case strings.Contains(path, "known_hosts"):
				output.Debug("Skipping known hosts file", path)
			default:
				readSSHKey(bytes, keys, info.ModTime(), basename(path))
			}
		}else {
			output.Error("Failed to read", path)
		}
	}()
	return keys
}

func basename(path string) string {
	if i := strings.LastIndex(path, "/"); i > 0 {
		i++
		return path[i:]
	} else {
		return path
	}
}

func readSSHKey(bytes []byte, keys chan data.Key, time time.Time, names ...string) {
	k := data.NewKey(string(bytes), time, names...)
	if k != nil {
		keys <- k
	}
}

func (c *FileConnection) Id() data.ID {
	return data.IdFromString(c.Path)
}
<|endoftext|>


<commit_before>package test

import (
	"io/ioutil"
	"testing"
	"time"

	"github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
	"github.com/ghodss/yaml"
	"github.com/golang/glog"
	params "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client/pipeline_service"
	model "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model"

	"github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model"
	uploadParams "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_upload_client/pipeline_upload_service"
	"github.com/kubeflow/pipelines/backend/src/common/client/api_server"
	"github.com/kubeflow/pipelines/backend/src/common/util"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
)

// This test suit tests various methods to import pipeline to pipeline system, including
// - upload yaml file
// - upload tarball file
// - providing YAML file url
// - Providing tarball file url
type PipelineApiTest struct {
	suite.Suite
	pipelineClient       *api_server.PipelineClient
	pipelineUploadClient *api_server.PipelineUploadClient
}

// Check the namespace have ML job installed and ready
func (s *PipelineApiTest) SetupTest() {
	err := waitForReady(*namespace, *initializeTimeout)
	if err != nil {
		glog.Exitf("Failed to initialize test. Error: %s", err.Error())
	}
	clientConfig := getClientConfig(*namespace)
	s.pipelineUploadClient, err = api_server.NewPipelineUploadClient(clientConfig, false)
	if err != nil {
		glog.Exitf("Failed to get pipeline upload client. Error: %s", err.Error())
	}
	s.pipelineClient, err = api_server.NewPipelineClient(clientConfig, false)
	if err != nil {
		glog.Exitf("Failed to get pipeline client. Error: %s", err.Error())
	}
}

func (s *PipelineApiTest) TestPipelineAPI() {
	t := s.T()

	deleteAllPipelines(s.pipelineClient, t)

	/* ---------- Upload pipelines YAML ---------- */
	argumentYAMLPipeline, err := s.pipelineUploadClient.UploadFile("resources/arguments-parameters.yaml", uploadParams.NewUploadPipelineParams())
	assert.Nil(t, err)
	assert.Equal(t, "arguments-parameters.yaml", argumentYAMLPipeline.Name)

	/* ---------- Upload the same pipeline again. Should fail due to name uniqueness ---------- */
	_, err = s.pipelineUploadClient.UploadFile("resources/arguments-parameters.yaml", uploadParams.NewUploadPipelineParams())
	assert.NotNil(t, err)
	assert.Contains(t, err.Error(), "Failed to upload pipeline.")

	/* ---------- Import pipeline YAML by URL ---------- */
	time.Sleep(1 * time.Second)
	sequentialPipeline, err := s.pipelineClient.Create(&params.CreatePipelineParams{
		Body: &pipeline_model.APIPipeline{URL: &pipeline_model.APIURL{
			PipelineURL: "https://storage.googleapis.com/ml-pipeline-dataset/sequential.yaml"}}})
	assert.Nil(t, err)
	assert.Equal(t, "sequential.yaml", sequentialPipeline.Name)

	/* ---------- Upload pipelines tarball ---------- */
	time.Sleep(1 * time.Second)
	argumentUploadPipeline, err := s.pipelineUploadClient.UploadFile(
		"resources/zip-arguments.tar.gz", &uploadParams.UploadPipelineParams{Name: util.StringPointer("zip-arguments-parameters")})
	assert.Equal(t, "zip-arguments-parameters", argumentUploadPipeline.Name)

	/* ---------- Import pipeline tarball by URL ---------- */
	time.Sleep(1 * time.Second)
	argumentUrlPipeline, err := s.pipelineClient.Create(&params.CreatePipelineParams{
		Body: &pipeline_model.APIPipeline{URL: &pipeline_model.APIURL{
			PipelineURL: "https://storage.googleapis.com/ml-pipeline-dataset/arguments.tar.gz"}}})
	assert.Nil(t, err)
	assert.Equal(t, "arguments.tar.gz", argumentUrlPipeline.Name)

	/* ---------- Verify list pipeline works ---------- */
	pipelines, _, err := s.pipelineClient.List(params.NewListPipelinesParams())
	assert.Nil(t, err)
	assert.Equal(t, 4, len(pipelines))
	for _, p := range pipelines {
		// Sampling one of the pipelines and verify the result is expected.
		if p.Name == "arguments-parameters.yaml" {
			verifyPipeline(t, p)
		}
	}

	/* ---------- Verify list pipeline sorted by names ---------- */
	listFirstPagePipelines, nextPageToken, err := s.pipelineClient.List(
		&params.ListPipelinesParams{PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listFirstPagePipelines))
	assert.Equal(t, "arguments-parameters.yaml", listFirstPagePipelines[0].Name)
	assert.Equal(t, "arguments.tar.gz", listFirstPagePipelines[1].Name)
	assert.NotEmpty(t, nextPageToken)

	listSecondPagePipelines, nextPageToken, err := s.pipelineClient.List(
		&params.ListPipelinesParams{PageToken: util.StringPointer(nextPageToken), PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listSecondPagePipelines))
	assert.Equal(t, "sequential.yaml", listSecondPagePipelines[0].Name)
	assert.Equal(t, "zip-arguments-parameters", listSecondPagePipelines[1].Name)
	assert.Empty(t, nextPageToken)

	/* ---------- Verify list pipeline sorted by creation time ---------- */
	listFirstPagePipelines, nextPageToken, err = s.pipelineClient.List(
		&params.ListPipelinesParams{PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("created_at")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listFirstPagePipelines))
	assert.Equal(t, "arguments-parameters.yaml", listFirstPagePipelines[0].Name)
	assert.Equal(t, "sequential.yaml", listFirstPagePipelines[1].Name)
	assert.NotEmpty(t, nextPageToken)

	listSecondPagePipelines, nextPageToken, err = s.pipelineClient.List(
		&params.ListPipelinesParams{PageToken: util.StringPointer(nextPageToken), PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("created_at")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listSecondPagePipelines))
	assert.Equal(t, "zip-arguments-parameters", listSecondPagePipelines[0].Name)
	assert.Equal(t, "arguments.tar.gz", listSecondPagePipelines[1].Name)
	assert.Empty(t, nextPageToken)

	/* ---------- List pipelines sort by unsupported description field. Should fail. ---------- */
	_, _, err = s.pipelineClient.List(&params.ListPipelinesParams{
		PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("unknownfield")})
	assert.NotNil(t, err)

	/* ---------- List pipelines sorted by names descend order ---------- */
	listFirstPagePipelines, nextPageToken, err = s.pipelineClient.List(
		&params.ListPipelinesParams{PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name desc")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listFirstPagePipelines))
	assert.Equal(t, "zip-arguments-parameters", listFirstPagePipelines[0].Name)
	assert.Equal(t, "sequential.yaml", listFirstPagePipelines[1].Name)
	assert.NotEmpty(t, nextPageToken)

	listSecondPagePipelines, nextPageToken, err = s.pipelineClient.List(&params.ListPipelinesParams{
		PageToken: util.StringPointer(nextPageToken), PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name desc")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listSecondPagePipelines))
	assert.Equal(t, "arguments.tar.gz", listSecondPagePipelines[0].Name)
	assert.Equal(t, "arguments-parameters.yaml", listSecondPagePipelines[1].Name)
	assert.Empty(t, nextPageToken)

	/* ---------- Verify get pipeline works ---------- */
	pipeline, err := s.pipelineClient.Get(&params.GetPipelineParams{ID: argumentYAMLPipeline.ID})
	assert.Nil(t, err)
	verifyPipeline(t, pipeline)

	/* ---------- Verify get template works ---------- */
	template, err := s.pipelineClient.GetTemplate(&params.GetTemplateParams{ID: argumentYAMLPipeline.ID})
	assert.Nil(t, err)
	expected, err := ioutil.ReadFile("resources/arguments-parameters.yaml")
	assert.Nil(t, err)
	var expectedWorkflow v1alpha1.Workflow
	err = yaml.Unmarshal(expected, &expectedWorkflow)
	assert.Equal(t, expectedWorkflow, *template)

	/* ---------- Clean up ---------- */
	deleteAllPipelines(s.pipelineClient, t)
}

func verifyPipeline(t *testing.T, pipeline *model.APIPipeline) {
	assert.NotNil(t, *pipeline)
	assert.NotNil(t, pipeline.CreatedAt)
	expected := model.APIPipeline{
		ID:        pipeline.ID,
		CreatedAt: pipeline.CreatedAt,
		Name:      "arguments-parameters.yaml",
		Parameters: []*model.APIParameter{
			{Name: "param1", Value: "hello"}, // Default value in the pipeline template
			{Name: "param2"},                 // No default value in the pipeline
		},
	}
	assert.Equal(t, expected, *pipeline)
}

func TestPipelineAPI(t *testing.T) {
	suite.Run(t, new(PipelineApiTest))
}
<commit_msg>update test to specify name when create pipeline (#543)<commit_after>package test

import (
	"io/ioutil"
	"testing"
	"time"

	"github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
	"github.com/ghodss/yaml"
	"github.com/golang/glog"
	params "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client/pipeline_service"
	model "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model"

	"github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model"
	uploadParams "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_upload_client/pipeline_upload_service"
	"github.com/kubeflow/pipelines/backend/src/common/client/api_server"
	"github.com/kubeflow/pipelines/backend/src/common/util"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
)

// This test suit tests various methods to import pipeline to pipeline system, including
// - upload yaml file
// - upload tarball file
// - providing YAML file url
// - Providing tarball file url
type PipelineApiTest struct {
	suite.Suite
	pipelineClient       *api_server.PipelineClient
	pipelineUploadClient *api_server.PipelineUploadClient
}

// Check the namespace have ML job installed and ready
func (s *PipelineApiTest) SetupTest() {
	err := waitForReady(*namespace, *initializeTimeout)
	if err != nil {
		glog.Exitf("Failed to initialize test. Error: %s", err.Error())
	}
	clientConfig := getClientConfig(*namespace)
	s.pipelineUploadClient, err = api_server.NewPipelineUploadClient(clientConfig, false)
	if err != nil {
		glog.Exitf("Failed to get pipeline upload client. Error: %s", err.Error())
	}
	s.pipelineClient, err = api_server.NewPipelineClient(clientConfig, false)
	if err != nil {
		glog.Exitf("Failed to get pipeline client. Error: %s", err.Error())
	}
}

func (s *PipelineApiTest) TestPipelineAPI() {
	t := s.T()

	deleteAllPipelines(s.pipelineClient, t)

	/* ---------- Upload pipelines YAML ---------- */
	argumentYAMLPipeline, err := s.pipelineUploadClient.UploadFile("resources/arguments-parameters.yaml", uploadParams.NewUploadPipelineParams())
	assert.Nil(t, err)
	assert.Equal(t, "arguments-parameters.yaml", argumentYAMLPipeline.Name)

	/* ---------- Upload the same pipeline again. Should fail due to name uniqueness ---------- */
	_, err = s.pipelineUploadClient.UploadFile("resources/arguments-parameters.yaml", uploadParams.NewUploadPipelineParams())
	assert.NotNil(t, err)
	assert.Contains(t, err.Error(), "Failed to upload pipeline.")

	/* ---------- Import pipeline YAML by URL ---------- */
	time.Sleep(1 * time.Second)
	sequentialPipeline, err := s.pipelineClient.Create(&params.CreatePipelineParams{
		Body: &pipeline_model.APIPipeline{Name:"sequential", URL: &pipeline_model.APIURL{
			PipelineURL: "https://storage.googleapis.com/ml-pipeline-dataset/sequential.yaml"}}})
	assert.Nil(t, err)
	assert.Equal(t, "sequential", sequentialPipeline.Name)

	/* ---------- Upload pipelines tarball ---------- */
	time.Sleep(1 * time.Second)
	argumentUploadPipeline, err := s.pipelineUploadClient.UploadFile(
		"resources/zip-arguments.tar.gz", &uploadParams.UploadPipelineParams{Name: util.StringPointer("zip-arguments-parameters")})
	assert.Equal(t, "zip-arguments-parameters", argumentUploadPipeline.Name)

	/* ---------- Import pipeline tarball by URL ---------- */
	time.Sleep(1 * time.Second)
	argumentUrlPipeline, err := s.pipelineClient.Create(&params.CreatePipelineParams{
		Body: &pipeline_model.APIPipeline{URL: &pipeline_model.APIURL{
			PipelineURL: "https://storage.googleapis.com/ml-pipeline-dataset/arguments.tar.gz"}}})
	assert.Nil(t, err)
	assert.Equal(t, "arguments.tar.gz", argumentUrlPipeline.Name)

	/* ---------- Verify list pipeline works ---------- */
	pipelines, _, err := s.pipelineClient.List(params.NewListPipelinesParams())
	assert.Nil(t, err)
	assert.Equal(t, 4, len(pipelines))
	for _, p := range pipelines {
		// Sampling one of the pipelines and verify the result is expected.
		if p.Name == "arguments-parameters.yaml" {
			verifyPipeline(t, p)
		}
	}

	/* ---------- Verify list pipeline sorted by names ---------- */
	listFirstPagePipelines, nextPageToken, err := s.pipelineClient.List(
		&params.ListPipelinesParams{PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listFirstPagePipelines))
	assert.Equal(t, "arguments-parameters.yaml", listFirstPagePipelines[0].Name)
	assert.Equal(t, "arguments.tar.gz", listFirstPagePipelines[1].Name)
	assert.NotEmpty(t, nextPageToken)

	listSecondPagePipelines, nextPageToken, err := s.pipelineClient.List(
		&params.ListPipelinesParams{PageToken: util.StringPointer(nextPageToken), PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listSecondPagePipelines))
	assert.Equal(t, "sequential", listSecondPagePipelines[0].Name)
	assert.Equal(t, "zip-arguments-parameters", listSecondPagePipelines[1].Name)
	assert.Empty(t, nextPageToken)

	/* ---------- Verify list pipeline sorted by creation time ---------- */
	listFirstPagePipelines, nextPageToken, err = s.pipelineClient.List(
		&params.ListPipelinesParams{PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("created_at")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listFirstPagePipelines))
	assert.Equal(t, "arguments-parameters.yaml", listFirstPagePipelines[0].Name)
	assert.Equal(t, "sequential", listFirstPagePipelines[1].Name)
	assert.NotEmpty(t, nextPageToken)

	listSecondPagePipelines, nextPageToken, err = s.pipelineClient.List(
		&params.ListPipelinesParams{PageToken: util.StringPointer(nextPageToken), PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("created_at")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listSecondPagePipelines))
	assert.Equal(t, "zip-arguments-parameters", listSecondPagePipelines[0].Name)
	assert.Equal(t, "arguments.tar.gz", listSecondPagePipelines[1].Name)
	assert.Empty(t, nextPageToken)

	/* ---------- List pipelines sort by unsupported description field. Should fail. ---------- */
	_, _, err = s.pipelineClient.List(&params.ListPipelinesParams{
		PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("unknownfield")})
	assert.NotNil(t, err)

	/* ---------- List pipelines sorted by names descend order ---------- */
	listFirstPagePipelines, nextPageToken, err = s.pipelineClient.List(
		&params.ListPipelinesParams{PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name desc")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listFirstPagePipelines))
	assert.Equal(t, "zip-arguments-parameters", listFirstPagePipelines[0].Name)
	assert.Equal(t, "sequential", listFirstPagePipelines[1].Name)
	assert.NotEmpty(t, nextPageToken)

	listSecondPagePipelines, nextPageToken, err = s.pipelineClient.List(&params.ListPipelinesParams{
		PageToken: util.StringPointer(nextPageToken), PageSize: util.Int32Pointer(2), SortBy: util.StringPointer("name desc")})
	assert.Nil(t, err)
	assert.Equal(t, 2, len(listSecondPagePipelines))
	assert.Equal(t, "arguments.tar.gz", listSecondPagePipelines[0].Name)
	assert.Equal(t, "arguments-parameters.yaml", listSecondPagePipelines[1].Name)
	assert.Empty(t, nextPageToken)

	/* ---------- Verify get pipeline works ---------- */
	pipeline, err := s.pipelineClient.Get(&params.GetPipelineParams{ID: argumentYAMLPipeline.ID})
	assert.Nil(t, err)
	verifyPipeline(t, pipeline)

	/* ---------- Verify get template works ---------- */
	template, err := s.pipelineClient.GetTemplate(&params.GetTemplateParams{ID: argumentYAMLPipeline.ID})
	assert.Nil(t, err)
	expected, err := ioutil.ReadFile("resources/arguments-parameters.yaml")
	assert.Nil(t, err)
	var expectedWorkflow v1alpha1.Workflow
	err = yaml.Unmarshal(expected, &expectedWorkflow)
	assert.Equal(t, expectedWorkflow, *template)

	/* ---------- Clean up ---------- */
	deleteAllPipelines(s.pipelineClient, t)
}

func verifyPipeline(t *testing.T, pipeline *model.APIPipeline) {
	assert.NotNil(t, *pipeline)
	assert.NotNil(t, pipeline.CreatedAt)
	expected := model.APIPipeline{
		ID:        pipeline.ID,
		CreatedAt: pipeline.CreatedAt,
		Name:      "arguments-parameters.yaml",
		Parameters: []*model.APIParameter{
			{Name: "param1", Value: "hello"}, // Default value in the pipeline template
			{Name: "param2"},                 // No default value in the pipeline
		},
	}
	assert.Equal(t, expected, *pipeline)
}

func TestPipelineAPI(t *testing.T) {
	suite.Run(t, new(PipelineApiTest))
}
<|endoftext|>


<commit_before>package columnize

import (
	"fmt"
	"strings"
)

// Returns a list of elements, each representing a single item which will
// belong to a column of output.
func getElementsFromLine(line string, delim string) []interface{} {
	elements := make([]interface{}, 0)
	for _, field := range strings.Split(line, delim) {
		elements = append(elements, strings.TrimSpace(field))
	}
	return elements
}

// Examines a list of strings and determines how wide each column should be
// considering all of the elements that need to be printed within it.
func getWidthsFromLines(lines []string, delim string) []int {
	var widths []int

	for _, line := range lines {
		elems := getElementsFromLine(line, delim)
		for i := 0; i < len(elems); i++ {
			if len(widths) <= i {
				widths = append(widths, len(elems[i].(string)))
			} else if widths[i] < len(elems[i].(string)) {
				widths[i] = len(elems[i].(string))
			}
		}
	}
	return widths
}

// Given a set of column widths and the number of columns in the current line,
// returns a sprintf-style format string which can be used to print output
// aligned properly with other lines using the same widths set.
func getStringFormat(widths []int, columns int, space string) string {
	var stringfmt string

	// Create the format string from the discovered widths
	for i := 0; i < columns && i < len(widths); i++ {
		if i == columns-1 {
			stringfmt += "%s\n"
		} else {
			stringfmt += fmt.Sprintf("%%-%ds%s", widths[i], space)
		}
	}
	return stringfmt
}

// Format is the public-facing interface that takes either a plain string
// or a list of strings, plus a delimiter, and returns nicely aligned output.
func Format(input interface{}, delim string, space string) (string, error) {
	var result string
	var lines []string

	switch in := input.(type) {
	case string:
		for _, line := range strings.Split(in, "\n") {
			lines = append(lines, line)
		}

	case []string:
		for _, line := range in {
			lines = append(lines, line)
		}

	default:
		return "", fmt.Errorf("columnize: Expected string or []string")
	}

	widths := getWidthsFromLines(lines, delim)

	// Create the formatted output using the format string
	for _, line := range lines {
		elems := getElementsFromLine(line, delim)
		stringfmt := getStringFormat(widths, len(elems), space)
		result += fmt.Sprintf(stringfmt, elems...)
	}
	return strings.TrimSpace(result), nil
}

// Convenience function for using Columnize as easy as possible.
func SimpleFormat(input interface{}) (string, error) {
	return Format(input, "|", "  ")
}
<commit_msg>Remove unnecessary loop and just do a direct assignment instead<commit_after>package columnize

import (
	"fmt"
	"strings"
)

// Returns a list of elements, each representing a single item which will
// belong to a column of output.
func getElementsFromLine(line string, delim string) []interface{} {
	elements := make([]interface{}, 0)
	for _, field := range strings.Split(line, delim) {
		elements = append(elements, strings.TrimSpace(field))
	}
	return elements
}

// Examines a list of strings and determines how wide each column should be
// considering all of the elements that need to be printed within it.
func getWidthsFromLines(lines []string, delim string) []int {
	var widths []int

	for _, line := range lines {
		elems := getElementsFromLine(line, delim)
		for i := 0; i < len(elems); i++ {
			if len(widths) <= i {
				widths = append(widths, len(elems[i].(string)))
			} else if widths[i] < len(elems[i].(string)) {
				widths[i] = len(elems[i].(string))
			}
		}
	}
	return widths
}

// Given a set of column widths and the number of columns in the current line,
// returns a sprintf-style format string which can be used to print output
// aligned properly with other lines using the same widths set.
func getStringFormat(widths []int, columns int, space string) string {
	var stringfmt string

	// Create the format string from the discovered widths
	for i := 0; i < columns && i < len(widths); i++ {
		if i == columns-1 {
			stringfmt += "%s\n"
		} else {
			stringfmt += fmt.Sprintf("%%-%ds%s", widths[i], space)
		}
	}
	return stringfmt
}

// Format is the public-facing interface that takes either a plain string
// or a list of strings, plus a delimiter, and returns nicely aligned output.
func Format(input interface{}, delim string, space string) (string, error) {
	var result string
	var lines []string

	switch in := input.(type) {
	case string:
		for _, line := range strings.Split(in, "\n") {
			lines = append(lines, line)
		}

	case []string:
		lines = in

	default:
		return "", fmt.Errorf("columnize: Expected string or []string")
	}

	widths := getWidthsFromLines(lines, delim)

	// Create the formatted output using the format string
	for _, line := range lines {
		elems := getElementsFromLine(line, delim)
		stringfmt := getStringFormat(widths, len(elems), space)
		result += fmt.Sprintf(stringfmt, elems...)
	}
	return strings.TrimSpace(result), nil
}

// Convenience function for using Columnize as easy as possible.
func SimpleFormat(input interface{}) (string, error) {
	return Format(input, "|", "  ")
}
<|endoftext|>


<commit_before>
package libgogo

import "testing"
import "./_obj/libgogo"

func TestStringLength(t *testing.T) {
    var len uint64;

    len = libgogo.StringLength("test");
    if len != 4 {
		t.Fatalf("libgogo.StringLength() = %d, want 4", len)
    }

    len = libgogo.StringLength("");
    if len != 0 {
		t.Fatalf("libgogo.StringLength() = %d, want 0", len)
    }

    len = libgogo.StringLength("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
    if len != 100 {
		t.Fatalf("libgogo.StringLength() = %d, want 100", len)
    }

    len = libgogo.StringLength("+-*/&|!{}[].,;=<>");
    if len != 17 {
		t.Fatalf("libgogo.StringLength() = %d, want 17", len)
    }
}

<commit_msg>libgogo_test: Fix StringLength checking and add StringCompare checking<commit_after>// Copyright 2010 The GoGo Authors. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package libgogo

import "testing"
import "./_obj/libgogo"

//
// Perform some basic checks on the libgogo.StringLength function
// This function is not capable of handling utf strings!
//
func TestStringLength(t *testing.T) {
    var len uint64;

    len = libgogo.StringLength("test");
    if len != 4 {
		t.Fatalf("libgogo.StringLength() = %d, want 4", len)
    }

    len = libgogo.StringLength("");
    if len != 0 {
		t.Fatalf("libgogo.StringLength() = %d, want 0", len)
    }

    len = libgogo.StringLength("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
    if len != 100 {
		t.Fatalf("libgogo.StringLength() = %d, want 100", len)
    }

    len = libgogo.StringLength("+-*/><=!&.");
    if len != 10 {
		t.Fatalf("libgogo.StringLength() = %d, want 10", len)
    }
}

//
// Perform basic comparison checks on libgogo.StringCompare function
//
func TestStringCompare(t *testing.T)  {
    var cmpFlag uint64;

    cmpFlag = libgogo.StringCompare("a","a");
    if cmpFlag != 0 {
        t.Fatalf("libgogo.StringCompare(\"a\") != 0, received %d", cmpFlag);
    }

    cmpFlag = libgogo.StringCompare("these strings","are not equal");
    if cmpFlag == 0 {
        t.Fatalf("libgogo.StringCompare(\"these strings\",\"are not equal\") == 0");
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2014, Rob Thornton
// All rights reserved.
// This source code is governed by a Simplied BSD-License. Please see the
// LICENSE included in this distribution for a copy of the full license
// or, if one is not included, you may also find a copy at
// http://opensource.org/licenses/BSD-2-Clause

// Package comp comprises the code generation portion of the Calc
// programming language
package comp

import (
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"

	"github.com/rthornton128/calc/ast"
	"github.com/rthornton128/calc/parse"
	"github.com/rthornton128/calc/token"
)

type compiler struct {
	fp       *os.File
	fset     *token.FileSet
	errors   token.ErrorList
	nextID   int
	curScope *ast.Scope
}

// CompileFile generates a C source file for the corresponding file
// specified by path. The .calc extension for the filename in path is
// replaced with .c for the C source output.
func CompileFile(path string, opt bool) error {
	var c compiler

	c.fset = token.NewFileSet()
	f, err := parse.ParseFile(c.fset, path, nil)
	if err != nil {
		return err
	}

	// type checking pass
	ast.Walk(f, &ast.TypeChecker{ErrorHandler: c.Error})

	// optimization pass(es)
	if opt {
		ast.Walk(f, &OptConstantFolder{})
	}

	path = path[:len(path)-len(filepath.Ext(path))]
	fp, err := os.Create(path + ".c")
	if err != nil {
		return err
	}
	defer fp.Close()

	c.fp = fp
	c.nextID = 1

	c.emitHeaders()
	c.compFile(f)
	c.emitMain()

	if c.errors.Count() != 0 {
		return c.errors
	}
	return nil
}

// CompileDir generates C source code for the Calc sources found in the
// directory specified by path. The C source file uses the same name as
// directory rather than any individual file.
func CompileDir(path string, opt bool) error {
	fs := token.NewFileSet()
	pkg, err := parse.ParseDir(fs, path)
	if err != nil {
		return err
	}

	// type checking pass
	ast.Walk(pkg, &ast.TypeChecker{})

	// optimization pass(es)
	if opt {
		ast.Walk(pkg, &OptConstantFolder{})
	}

	fp, err := os.Create(filepath.Join(path, filepath.Base(path)) + ".c")
	if err != nil {
		return err
	}
	defer fp.Close()

	c := &compiler{fp: fp, fset: fs, nextID: 1}

	c.emitHeaders()
	c.compPackage(pkg)
	c.emitMain()

	if c.errors.Count() != 0 {
		return c.errors
	}
	return nil
}

/* Utility */

func cType(t ast.Type) string {
	switch t {
	case ast.Int:
		return "int32_t"
	default:
		return "int"
	}
}

// Error adds an error to the compiler at the given position. The remaining
// arguments are used to generate the error message.
func (c *compiler) Error(pos token.Pos, args ...interface{}) {
	c.errors.Add(c.fset.Position(pos), args...)
}

func (c *compiler) emit(s string, args ...interface{}) {
	fmt.Fprintf(c.fp, s, args...)
}

func (c *compiler) emitln(args ...interface{}) {
	fmt.Fprintln(c.fp, args...)
}

func (c *compiler) emitHeaders() {
	c.emitln("#include <stdio.h>")
	c.emitln("#include <stdint.h>")
}

func (c *compiler) emitMain() {
	c.emitln("int main(void) {")
	c.emitln("printf(\"%d\\n\", _main());")
	c.emitln("return 0;")
	c.emitln("}")
}

func (c *compiler) getID(id int) int {
	if id == 0 {
		id = c.nextID
		c.nextID++
	}
	return id
}

/* Scope */

func (c *compiler) openScope(s *ast.Scope) {
	c.curScope = s
}

func (c *compiler) closeScope() {
	c.curScope = c.curScope.Parent
}

/* Main Compiler */

type temp struct {
	ID int
}

func (t *temp) Pos() token.Pos { return token.NoPos }
func (t *temp) End() token.Pos { return token.NoPos }

func (c *compiler) compNode(node ast.Node) string {
	var str string
	switch n := node.(type) {
	case *ast.AssignExpr:
		c.compAssignExpr(n)
	case *ast.BasicLit:
		str = c.compBasicLit(n)
	case *ast.BinaryExpr:
		str = c.compBinaryExpr(n)
	case *ast.CallExpr:
		str = c.compCallExpr(n)
	case *ast.DeclExpr:
		c.compDeclExpr(n)
	case *ast.ExprList:
		for _, e := range n.List {
			str = c.compNode(e)
		}
	case *ast.Ident:
		str = c.compIdent(n)
	case *ast.IfExpr:
		str = c.compIfExpr(n)
	case *ast.UnaryExpr:
		c.compUnaryExpr(n)
	case *ast.Value:
		str = fmt.Sprintf("%d", n.Value)
	case *ast.VarExpr:
		c.compVarExpr(n)
	}
	return str
}

func (c *compiler) compAssignExpr(a *ast.AssignExpr) {
	c.emit("%s = %s;\n", c.compNode(a.Name), c.compNode(a.Value))
}

func (c *compiler) compBasicLit(b *ast.BasicLit) string {
	// use switch b.Kind {} when future types are added
	i, err := strconv.Atoi(b.Lit)
	if err != nil {
		c.Error(b.Pos(), "bad conversion:", err)
	}
	return fmt.Sprintf("%d", i)
}

func (c *compiler) compBinaryExpr(b *ast.BinaryExpr) string {
	lhs := ast.Node(b.List[0])

	for _, rhs := range b.List[1:] {
		c.emit("%s _v%d = %s %s %s;\n",
			cType(b.RealType),
			c.nextID,
			c.compNode(lhs),
			b.Op,
			c.compNode(rhs))
		lhs = &temp{ID: c.getID(b.ID)}
	}
	b.ID = c.getID(lhs.(*temp).ID)
	return fmt.Sprintf("_v%d", b.ID)
}

func (c *compiler) compCallExpr(e *ast.CallExpr) string {
	args := make([]string, len(e.Args))
	for i, a := range e.Args {
		args[i] = c.compNode(a)
	}
	return fmt.Sprintf("_%s(%s)", e.Name.Name, strings.Join(args, ","))
}

func (c *compiler) compDeclExpr(d *ast.DeclExpr) {
	params := make([]string, len(d.Params))
	for i, p := range d.Params {
		params[i] = cType(p.Object.RealType) + " " + c.compNode(p)
	}
	c.emit("%s _%s(%s) {\n",
		cType(d.RealType),
		d.Name.Name,
		strings.Join(params, ","))
	c.emit("return %s;\n}\n", c.compNode(d.Body))
}

func (c *compiler) compFile(f *ast.File) {
	c.compDeclProto(f)
}

func (c *compiler) compIdent(i *ast.Ident) string {
	i.Object.ID = c.getID(i.Object.ID)
	return fmt.Sprintf("_v%d", i.Object.ID)
}

func (c *compiler) compIfExpr(n *ast.IfExpr) string {
	t := &temp{ID: c.getID(0)}
	c.emit("%s _v%d = 0;\n", cType(n.RealType), t.ID)
	c.emit("if (%s == 1) {\n", c.compNode(n.Cond))
	c.emit("_v%d = %s;\n", t.ID, c.compNode(n.Then))
	if n.Else != nil && !reflect.ValueOf(n.Else).IsNil() {
		c.emitln("} else {")
		c.emit("_v%d = %s;\n", t.ID, c.compNode(n.Else))
	}
	c.emitln("}")
	return fmt.Sprintf("_v%d", t.ID)
}

func (c *compiler) compPackage(p *ast.Package) {
	for _, f := range p.Files {
		c.compFile(f)
	}
}

func (c *compiler) compDeclProto(f *ast.File) {
	for _, decl := range f.Decls {
		params := make([]string, len(decl.Params))
		for i, p := range decl.Params {
			//fmt.Println("proto:", p.Object == nil)
			params[i] = cType(p.Object.RealType) + " " + c.compNode(p)
		}
		c.emit("%s _%s(%s);\n",
			cType(decl.RealType),
			decl.Name.Name,
			strings.Join(params, ","))
		defer c.compNode(decl)
	}
}

func (c *compiler) compUnaryExpr(u *ast.UnaryExpr) string {
	return fmt.Sprintf("-(%s)", c.compNode(u.Value))
}

func (c *compiler) compVarExpr(v *ast.VarExpr) {
	c.emit("%s %s;\n", cType(v.RealType), c.compNode(v.Name))
	if v.Object.Value != nil && !reflect.ValueOf(v.Object.Value).IsNil() {
		if val, ok := v.Object.Value.(*ast.AssignExpr); ok {
			c.compAssignExpr(val)
			return
		}
		panic("parsing error occured, object's Value is not an assignment")
	}
}
<commit_msg>remove unused scoping code<commit_after>// Copyright (c) 2014, Rob Thornton
// All rights reserved.
// This source code is governed by a Simplied BSD-License. Please see the
// LICENSE included in this distribution for a copy of the full license
// or, if one is not included, you may also find a copy at
// http://opensource.org/licenses/BSD-2-Clause

// Package comp comprises the code generation portion of the Calc
// programming language
package comp

import (
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"

	"github.com/rthornton128/calc/ast"
	"github.com/rthornton128/calc/parse"
	"github.com/rthornton128/calc/token"
)

type compiler struct {
	fp       *os.File
	fset     *token.FileSet
	errors   token.ErrorList
	nextID   int
	curScope *ast.Scope
}

// CompileFile generates a C source file for the corresponding file
// specified by path. The .calc extension for the filename in path is
// replaced with .c for the C source output.
func CompileFile(path string, opt bool) error {
	var c compiler

	c.fset = token.NewFileSet()
	f, err := parse.ParseFile(c.fset, path, nil)
	if err != nil {
		return err
	}

	// type checking pass
	ast.Walk(f, &ast.TypeChecker{ErrorHandler: c.Error})

	// optimization pass(es)
	if opt {
		ast.Walk(f, &OptConstantFolder{})
	}

	path = path[:len(path)-len(filepath.Ext(path))]
	fp, err := os.Create(path + ".c")
	if err != nil {
		return err
	}
	defer fp.Close()

	c.fp = fp
	c.nextID = 1

	c.emitHeaders()
	c.compFile(f)
	c.emitMain()

	if c.errors.Count() != 0 {
		return c.errors
	}
	return nil
}

// CompileDir generates C source code for the Calc sources found in the
// directory specified by path. The C source file uses the same name as
// directory rather than any individual file.
func CompileDir(path string, opt bool) error {
	fs := token.NewFileSet()
	pkg, err := parse.ParseDir(fs, path)
	if err != nil {
		return err
	}

	// type checking pass
	ast.Walk(pkg, &ast.TypeChecker{})

	// optimization pass(es)
	if opt {
		ast.Walk(pkg, &OptConstantFolder{})
	}

	fp, err := os.Create(filepath.Join(path, filepath.Base(path)) + ".c")
	if err != nil {
		return err
	}
	defer fp.Close()

	c := &compiler{fp: fp, fset: fs, nextID: 1}

	c.emitHeaders()
	c.compPackage(pkg)
	c.emitMain()

	if c.errors.Count() != 0 {
		return c.errors
	}
	return nil
}

/* Utility */

func cType(t ast.Type) string {
	switch t {
	case ast.Int:
		return "int32_t"
	default:
		return "int"
	}
}

// Error adds an error to the compiler at the given position. The remaining
// arguments are used to generate the error message.
func (c *compiler) Error(pos token.Pos, args ...interface{}) {
	c.errors.Add(c.fset.Position(pos), args...)
}

func (c *compiler) emit(s string, args ...interface{}) {
	fmt.Fprintf(c.fp, s, args...)
}

func (c *compiler) emitln(args ...interface{}) {
	fmt.Fprintln(c.fp, args...)
}

func (c *compiler) emitHeaders() {
	c.emitln("#include <stdio.h>")
	c.emitln("#include <stdint.h>")
}

func (c *compiler) emitMain() {
	c.emitln("int main(void) {")
	c.emitln("printf(\"%d\\n\", _main());")
	c.emitln("return 0;")
	c.emitln("}")
}

func (c *compiler) getID(id int) int {
	if id == 0 {
		id = c.nextID
		c.nextID++
	}
	return id
}

/* Main Compiler */

type temp struct {
	ID int
}

func (t *temp) Pos() token.Pos { return token.NoPos }
func (t *temp) End() token.Pos { return token.NoPos }

func (c *compiler) compNode(node ast.Node) string {
	var str string
	switch n := node.(type) {
	case *ast.AssignExpr:
		c.compAssignExpr(n)
	case *ast.BasicLit:
		str = c.compBasicLit(n)
	case *ast.BinaryExpr:
		str = c.compBinaryExpr(n)
	case *ast.CallExpr:
		str = c.compCallExpr(n)
	case *ast.DeclExpr:
		c.compDeclExpr(n)
	case *ast.ExprList:
		for _, e := range n.List {
			str = c.compNode(e)
		}
	case *ast.Ident:
		str = c.compIdent(n)
	case *ast.IfExpr:
		str = c.compIfExpr(n)
	case *ast.UnaryExpr:
		c.compUnaryExpr(n)
	case *ast.Value:
		str = fmt.Sprintf("%d", n.Value)
	case *ast.VarExpr:
		c.compVarExpr(n)
	}
	return str
}

func (c *compiler) compAssignExpr(a *ast.AssignExpr) {
	c.emit("%s = %s;\n", c.compNode(a.Name), c.compNode(a.Value))
}

func (c *compiler) compBasicLit(b *ast.BasicLit) string {
	// use switch b.Kind {} when future types are added
	i, err := strconv.Atoi(b.Lit)
	if err != nil {
		c.Error(b.Pos(), "bad conversion:", err)
	}
	return fmt.Sprintf("%d", i)
}

func (c *compiler) compBinaryExpr(b *ast.BinaryExpr) string {
	lhs := ast.Node(b.List[0])

	for _, rhs := range b.List[1:] {
		c.emit("%s _v%d = %s %s %s;\n",
			cType(b.RealType),
			c.nextID,
			c.compNode(lhs),
			b.Op,
			c.compNode(rhs))
		lhs = &temp{ID: c.getID(b.ID)}
	}
	b.ID = c.getID(lhs.(*temp).ID)
	return fmt.Sprintf("_v%d", b.ID)
}

func (c *compiler) compCallExpr(e *ast.CallExpr) string {
	args := make([]string, len(e.Args))
	for i, a := range e.Args {
		args[i] = c.compNode(a)
	}
	return fmt.Sprintf("_%s(%s)", e.Name.Name, strings.Join(args, ","))
}

func (c *compiler) compDeclExpr(d *ast.DeclExpr) {
	params := make([]string, len(d.Params))
	for i, p := range d.Params {
		params[i] = cType(p.Object.RealType) + " " + c.compNode(p)
	}
	c.emit("%s _%s(%s) {\n",
		cType(d.RealType),
		d.Name.Name,
		strings.Join(params, ","))
	c.emit("return %s;\n}\n", c.compNode(d.Body))
}

func (c *compiler) compFile(f *ast.File) {
	c.compDeclProto(f)
}

func (c *compiler) compIdent(i *ast.Ident) string {
	i.Object.ID = c.getID(i.Object.ID)
	return fmt.Sprintf("_v%d", i.Object.ID)
}

func (c *compiler) compIfExpr(n *ast.IfExpr) string {
	t := &temp{ID: c.getID(0)}
	c.emit("%s _v%d = 0;\n", cType(n.RealType), t.ID)
	c.emit("if (%s == 1) {\n", c.compNode(n.Cond))
	c.emit("_v%d = %s;\n", t.ID, c.compNode(n.Then))
	if n.Else != nil && !reflect.ValueOf(n.Else).IsNil() {
		c.emitln("} else {")
		c.emit("_v%d = %s;\n", t.ID, c.compNode(n.Else))
	}
	c.emitln("}")
	return fmt.Sprintf("_v%d", t.ID)
}

func (c *compiler) compPackage(p *ast.Package) {
	for _, f := range p.Files {
		c.compFile(f)
	}
}

func (c *compiler) compDeclProto(f *ast.File) {
	for _, decl := range f.Decls {
		params := make([]string, len(decl.Params))
		for i, p := range decl.Params {
			params[i] = cType(p.Object.RealType) + " " + c.compNode(p)
		}
		c.emit("%s _%s(%s);\n",
			cType(decl.RealType),
			decl.Name.Name,
			strings.Join(params, ","))
		defer c.compNode(decl)
	}
}

func (c *compiler) compUnaryExpr(u *ast.UnaryExpr) string {
	return fmt.Sprintf("-(%s)", c.compNode(u.Value))
}

func (c *compiler) compVarExpr(v *ast.VarExpr) {
	c.emit("%s %s;\n", cType(v.RealType), c.compNode(v.Name))
	if v.Object.Value != nil && !reflect.ValueOf(v.Object.Value).IsNil() {
		if val, ok := v.Object.Value.(*ast.AssignExpr); ok {
			c.compAssignExpr(val)
			return
		}
		panic("parsing error occured, object's Value is not an assignment")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"path/filepath"
	"time"

	"github.com/gofrs/flock"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/client-go/pkg/apis/clientauthentication"
	clientauthv1alpha1 "k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1"
	"k8s.io/klog"
)

const (
	modeTPM      = "tpm"
	modeAltToken = "alt-token"
	flockName    = "kubelet-client.lock"
)

var (
	mode = flag.String("mode", modeTPM, "Plugin mode, one of ['tpm', 'alt-token'].")
	// TPM flags.
	cacheDir = flag.String("cache-dir", "/var/lib/kubelet/pki", "Path to directory to store key and certificate.")
	tpmPath  = flag.String("tpm-path", "/dev/tpm0", "path to a TPM character device or socket.")

	altTokenURL  = flag.String("alt-token-url", "", "URL to token endpoint.")
	altTokenBody = flag.String("alt-token-body", "", "Body of token request.")

	scheme       = runtime.NewScheme()
	codecs       = serializer.NewCodecFactory(scheme)
	groupVersion = schema.GroupVersion{
		Group:   "client.authentication.k8s.io",
		Version: "v1alpha1",
	}
)

func init() {
	metav1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
	clientauthv1alpha1.AddToScheme(scheme)
	clientauthentication.AddToScheme(scheme)

	// Override the default in klog. There's verbosity flag for suppressing output.
	flag.Set("logtostderr", "true")
}

func main() {
	flag.Parse()

	var key, cert []byte
	var token string
	var err error

	switch *mode {
	case modeTPM:
		// Lock around certificate reading and CSRs. Prevents parallel
		// invocations creating duplicate CSRs if there is no cert yet.
		fileLock := flock.New(filepath.Join(*cacheDir, flockName))
		if err = fileLock.Lock(); err != nil {
			klog.Exit(err)
		}
		defer fileLock.Unlock()

		key, cert, err = getKeyCert(*cacheDir, requestCertificate)
		if err != nil {
			klog.Exit(err)
		}
	case modeAltToken:
		if *altTokenURL == "" {
			klog.Exit("--alt-token-url must be set")
		}
		if *altTokenBody == "" {
			klog.Exit("--alt-token-body must be set")
		}
		tok, err := newAltTokenSource(*altTokenURL, *altTokenBody).Token()
		if err != nil {
			klog.Exit(err)
		}
		token = tok.AccessToken
	default:
		klog.Exitf("unrecognized --mode value %q, want one of [%q, %q]", *mode, modeAltToken, modeTPM)
	}

	if err := writeResponse(token, key, cert); err != nil {
		klog.Exit(err)
	}
}

func writeResponse(token string, key, cert []byte) error {
	resp := &clientauthentication.ExecCredential{
		Status: &clientauthentication.ExecCredentialStatus{
			// Make Kubelet poke us every hour, we'll cache the cert for longer.
			ExpirationTimestamp:   &metav1.Time{time.Now().Add(responseExpiry)},
			Token:                 token,
			ClientCertificateData: string(cert),
			ClientKeyData:         string(key),
		},
	}
	data, err := runtime.Encode(codecs.LegacyCodec(groupVersion), resp)
	if err != nil {
		return err
	}
	fmt.Print(string(data))
	return nil
}
<commit_msg>Add klog.InitFlags to correctly handle klog flags.<commit_after>package main

import (
	"flag"
	"fmt"
	"path/filepath"
	"time"

	"github.com/gofrs/flock"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/client-go/pkg/apis/clientauthentication"
	clientauthv1alpha1 "k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1"
	"k8s.io/klog"
)

const (
	modeTPM      = "tpm"
	modeAltToken = "alt-token"
	flockName    = "kubelet-client.lock"
)

var (
	mode = flag.String("mode", modeTPM, "Plugin mode, one of ['tpm', 'alt-token'].")
	// TPM flags.
	cacheDir = flag.String("cache-dir", "/var/lib/kubelet/pki", "Path to directory to store key and certificate.")
	tpmPath  = flag.String("tpm-path", "/dev/tpm0", "path to a TPM character device or socket.")

	altTokenURL  = flag.String("alt-token-url", "", "URL to token endpoint.")
	altTokenBody = flag.String("alt-token-body", "", "Body of token request.")

	scheme       = runtime.NewScheme()
	codecs       = serializer.NewCodecFactory(scheme)
	groupVersion = schema.GroupVersion{
		Group:   "client.authentication.k8s.io",
		Version: "v1alpha1",
	}
)

func init() {
	metav1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
	clientauthv1alpha1.AddToScheme(scheme)
	clientauthentication.AddToScheme(scheme)
}

func main() {
	klog.InitFlags(nil)
	defer klog.Flush()
	flag.Set("logtostderr", "true")
	flag.Parse()

	var key, cert []byte
	var token string
	var err error

	switch *mode {
	case modeTPM:
		// Lock around certificate reading and CSRs. Prevents parallel
		// invocations creating duplicate CSRs if there is no cert yet.
		fileLock := flock.New(filepath.Join(*cacheDir, flockName))
		if err = fileLock.Lock(); err != nil {
			klog.Exit(err)
		}
		defer fileLock.Unlock()

		key, cert, err = getKeyCert(*cacheDir, requestCertificate)
		if err != nil {
			klog.Exit(err)
		}
	case modeAltToken:
		if *altTokenURL == "" {
			klog.Exit("--alt-token-url must be set")
		}
		if *altTokenBody == "" {
			klog.Exit("--alt-token-body must be set")
		}
		tok, err := newAltTokenSource(*altTokenURL, *altTokenBody).Token()
		if err != nil {
			klog.Exit(err)
		}
		token = tok.AccessToken
	default:
		klog.Exitf("unrecognized --mode value %q, want one of [%q, %q]", *mode, modeAltToken, modeTPM)
	}

	if err := writeResponse(token, key, cert); err != nil {
		klog.Exit(err)
	}
}

func writeResponse(token string, key, cert []byte) error {
	resp := &clientauthentication.ExecCredential{
		Status: &clientauthentication.ExecCredentialStatus{
			// Make Kubelet poke us every hour, we'll cache the cert for longer.
			ExpirationTimestamp:   &metav1.Time{time.Now().Add(responseExpiry)},
			Token:                 token,
			ClientCertificateData: string(cert),
			ClientKeyData:         string(key),
		},
	}
	data, err := runtime.Encode(codecs.LegacyCodec(groupVersion), resp)
	if err != nil {
		return err
	}
	fmt.Print(string(data))
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"os"
	"sync"

	"github.com/didenko/mboxrd"
)

var (
	lg     *log.Logger = log.New(os.Stderr, "", log.LstdFlags)
	err    error
	mbox   string
	dir    string
	email  string
	emlWG  sync.WaitGroup
	origWG sync.WaitGroup
	workWG sync.WaitGroup
)

func logErrors(lg *log.Logger, errors chan error) {
	for err := range errors {
		lg.Println(err)
	}
}

func init() {

	flag.StringVar(&dir, "dir", "", "A directory to put the resulting messages to")
	flag.StringVar(&mbox, "mbox", "", "An mbox file to process")
	flag.StringVar(&email, "email", "", "An email which correspondence to be captured")
	flag.Parse()

	if dir == "" || mbox == "" || email == "" {
		lg.Fatal("All of: dir, mbox, and email parameters are required")
	}

	fi, err := os.Stat(dir)
	if err != nil {
		lg.Fatalf("Failed to open the path %q: %s\n", dir, err)
	}

	if !fi.Mode().IsDir() {
		lg.Fatalf("Error: the %q path is not a directory", dir)
	}
}

func main() {

	mboxFile, err := os.Open(mbox)
	if err != nil {
		lg.Panic(err)
	}
	defer mboxFile.Close()

	messages := make(chan chan string)
	emlNames := make(chan string)
	errors := make(chan error)

	go logErrors(lg, errors)

	go mboxrd.Extract(mboxFile, messages, errors)

	workWG.Add(1)
	go func() {
		defer workWG.Done()
		for message := range messages {
			origWG.Add(1)
			go mboxrd.WriteOriginal(
				message,
				emlNames,
				errors,
				dir,
				mboxrd.AllWith([]string{email}, errors),
				mboxrd.NameFromTimeUser("%s_%s.eml", errors),
				&origWG)
		}
	}()

	go func() {
		defer workWG.Done()
		for eml := range emlNames {
			emlWG.Add(1)
			go mboxrd.UnpackMessage(
				eml,
				errors,
				&emlWG)
		}
	}()

	workWG.Wait()
	origWG.Wait()
	emlWG.Wait()
}
<commit_msg>Stray workgroup close (follow-up for#2)<commit_after>package main

import (
	"flag"
	"log"
	"os"
	"sync"

	"github.com/didenko/mboxrd"
)

var (
	lg     *log.Logger = log.New(os.Stderr, "", log.LstdFlags)
	err    error
	mbox   string
	dir    string
	email  string
	emlWG  sync.WaitGroup
	origWG sync.WaitGroup
	workWG sync.WaitGroup
)

func logErrors(lg *log.Logger, errors chan error) {
	for err := range errors {
		lg.Println(err)
	}
}

func init() {

	flag.StringVar(&dir, "dir", "", "A directory to put the resulting messages to")
	flag.StringVar(&mbox, "mbox", "", "An mbox file to process")
	flag.StringVar(&email, "email", "", "An email which correspondence to be captured")
	flag.Parse()

	if dir == "" || mbox == "" || email == "" {
		lg.Fatal("All of: dir, mbox, and email parameters are required")
	}

	fi, err := os.Stat(dir)
	if err != nil {
		lg.Fatalf("Failed to open the path %q: %s\n", dir, err)
	}

	if !fi.Mode().IsDir() {
		lg.Fatalf("Error: the %q path is not a directory", dir)
	}
}

func main() {

	mboxFile, err := os.Open(mbox)
	if err != nil {
		lg.Panic(err)
	}
	defer mboxFile.Close()

	messages := make(chan chan string)
	emlNames := make(chan string)
	errors := make(chan error)

	go logErrors(lg, errors)

	go mboxrd.Extract(mboxFile, messages, errors)

	workWG.Add(1)
	go func() {
		defer workWG.Done()
		for message := range messages {
			origWG.Add(1)
			go mboxrd.WriteOriginal(
				message,
				emlNames,
				errors,
				dir,
				mboxrd.AllWith([]string{email}, errors),
				mboxrd.NameFromTimeUser("%s_%s.eml", errors),
				&origWG)
		}
	}()

	go func() {
		for eml := range emlNames {
			emlWG.Add(1)
			go mboxrd.UnpackMessage(
				eml,
				errors,
				&emlWG)
		}
	}()

	workWG.Wait()
	origWG.Wait()
	emlWG.Wait()
}
<|endoftext|>