How to use Close method of overlap Package

Best Mock code snippet using overlap.Close

artifact_streams_test.go

Source:artifact_streams_test.go Github

copy

Full Screen

...7	"testing"8	"github.com/stretchr/testify/assert"9	"github.com/stretchr/testify/require"10)11type readCloserTester struct {12	reader io.ReadCloser13	called int14}15func (r *readCloserTester) Read(p []byte) (n int, err error) {16	return r.reader.Read(p)17}18func (r *readCloserTester) Close() error {19	r.called++20	return r.reader.Close()21}22type streamCloserTester struct {23	stream ArtifactStream24	called int25}26func (s *streamCloserTester) Next() (string, error) {27	return s.stream.Next()28}29func (s *streamCloserTester) Close() error {30	s.called++31	return s.stream.Close()32}33func TestPeekableStream(t *testing.T) {34	t.Run("returns EOF for empty stream", func(t *testing.T) {35		a := NewPeekableStream(NewArrayStream([]string{}))36		_, err := a.Peek()37		assert.Equal(t, io.EOF, err)38		_, err = a.Peek()39		assert.Equal(t, io.EOF, err)40		_, err = a.Next()41		assert.Equal(t, io.EOF, err)42		_, err = a.Next()43		assert.Equal(t, io.EOF, err)44	})45	t.Run("one element", func(t *testing.T) {46		a := NewPeekableStream(NewArrayStream([]string{"a"}))47		v, err := a.Peek()48		require.NoError(t, err)49		assert.Equal(t, "a", v)50		v, err = a.Peek()51		require.NoError(t, err)52		assert.Equal(t, "a", v)53		v, err = a.Next()54		require.NoError(t, err)55		assert.Equal(t, "a", v)56		v, err = a.Next()57		require.Equal(t, io.EOF, err)58		v, err = a.Peek()59		require.Equal(t, io.EOF, err)60	})61	t.Run("multiple element", func(t *testing.T) {62		a := NewPeekableStream(NewArrayStream([]string{"a", "b"}))63		v, err := a.Peek()64		require.NoError(t, err)65		assert.Equal(t, "a", v)66		v, err = a.Next()67		require.NoError(t, err)68		assert.Equal(t, "a", v)69		v, err = a.Peek()70		require.NoError(t, err)71		assert.Equal(t, "b", v)72		v, err = a.Peek()73		require.NoError(t, err)74		assert.Equal(t, "b", v)75		_, err = a.Next()76		require.NoError(t, err)77		assert.Equal(t, "b", v)78		_, err = a.Peek()79		require.Equal(t, io.EOF, err)80		_, err = a.Next()81		require.Equal(t, io.EOF, err)82	})83	t.Run("closes underlying stream", func(t *testing.T) {84		tester := &streamCloserTester{85			stream: EmptyStream(),86		}87		reader := NewPeekableStream(tester)88		require.NoError(t, reader.Close())89		require.NoError(t, reader.Close())90		assert.Equal(t, 1, tester.called)91	})92}93func TestLineReaderStream(t *testing.T) {94	t.Run("empty", func(t *testing.T) {95		buffer := ioutil.NopCloser(bytes.NewBuffer(nil))96		reader := NewLineReaderStream(buffer)97		assert.Equal(t, []string{}, consume(t, reader))98	})99	t.Run("compact", func(t *testing.T) {100		buffer := ioutil.NopCloser(bytes.NewBufferString("a\nb\nc"))101		reader := NewLineReaderStream(buffer)102		assert.Equal(t, []string{"a", "b", "c"}, consume(t, reader))103	})104	t.Run("compact with trailing newline", func(t *testing.T) {105		buffer := ioutil.NopCloser(bytes.NewBufferString("a\nb\nc\n"))106		reader := NewLineReaderStream(buffer)107		assert.Equal(t, []string{"a", "b", "c"}, consume(t, reader))108	})109	t.Run("multiple trailing newline", func(t *testing.T) {110		buffer := ioutil.NopCloser(bytes.NewBufferString("a\nb\nc\n\n\n"))111		reader := NewLineReaderStream(buffer)112		assert.Equal(t, []string{"a", "b", "c"}, consume(t, reader))113	})114	t.Run("starting newline", func(t *testing.T) {115		buffer := ioutil.NopCloser(bytes.NewBufferString("\na\nb\nc\n"))116		reader := NewLineReaderStream(buffer)117		assert.Equal(t, []string{"a", "b", "c"}, consume(t, reader))118	})119	t.Run("newlines in middle", func(t *testing.T) {120		buffer := ioutil.NopCloser(bytes.NewBufferString("\na\n\n\nb\n\nc\n"))121		reader := NewLineReaderStream(buffer)122		assert.Equal(t, []string{"a", "b", "c"}, consume(t, reader))123	})124	t.Run("chomps whitespace", func(t *testing.T) {125		buffer := ioutil.NopCloser(bytes.NewBufferString(" \na \n \n\n b\n  \nc \n "))126		reader := NewLineReaderStream(buffer)127		assert.Equal(t, []string{"a", "b", "c"}, consume(t, reader))128	})129	t.Run("closes underlying stream", func(t *testing.T) {130		readCloserTester := &readCloserTester{131			reader: ioutil.NopCloser(bytes.NewBufferString("a\nb\nc")),132		}133		reader := NewLineReaderStream(readCloserTester)134		assert.Equal(t, []string{"a", "b", "c"}, consume(t, reader))135		require.NoError(t, reader.Close())136		require.NoError(t, reader.Close())137		assert.Equal(t, 1, readCloserTester.called)138	})139}140func TestXor(t *testing.T) {141	t.Run("a is empty", func(t *testing.T) {142		a := NewArrayStream([]string{})143		b := NewArrayStream([]string{"a", "c", "d"})144		c := Xor(a, b)145		assert.Equal(t, consume(t, c), []string{"a", "c", "d"})146	})147	t.Run("b is empty", func(t *testing.T) {148		a := NewArrayStream([]string{"a", "c", "d"})149		b := NewArrayStream([]string{})150		c := Xor(a, b)151		assert.Equal(t, consume(t, c), []string{"a", "c", "d"})152	})153	t.Run("both empty", func(t *testing.T) {154		a := NewArrayStream([]string{})155		b := NewArrayStream([]string{})156		c := Xor(a, b)157		assert.Equal(t, consume(t, c), []string{})158	})159	t.Run("no difference", func(t *testing.T) {160		a := NewArrayStream([]string{"a", "c", "d"})161		b := NewArrayStream([]string{"a", "c", "d"})162		c := Xor(a, b)163		assert.Equal(t, consume(t, c), []string{})164	})165	t.Run("a is longer", func(t *testing.T) {166		a := NewArrayStream([]string{"a", "c", "d"})167		b := NewArrayStream([]string{"a", "c"})168		c := Xor(a, b)169		assert.Equal(t, consume(t, c), []string{"d"})170	})171	t.Run("b is longer", func(t *testing.T) {172		a := NewArrayStream([]string{"a", "c"})173		b := NewArrayStream([]string{"a", "c", "d"})174		c := Xor(a, b)175		assert.Equal(t, consume(t, c), []string{"d"})176	})177	t.Run("ends are different 1", func(t *testing.T) {178		a := NewArrayStream([]string{"a", "c", "d", "f"})179		b := NewArrayStream([]string{"b", "c", "d", "e"})180		c := Xor(a, b)181		assert.Equal(t, consume(t, c), []string{"a", "b", "e", "f"})182	})183	t.Run("ends are different 2", func(t *testing.T) {184		a := NewArrayStream([]string{"a", "c", "d", "f"})185		b := NewArrayStream([]string{"b", "c", "d", "e", "g"})186		c := Xor(a, b)187		assert.Equal(t, consume(t, c), []string{"a", "b", "e", "f", "g"})188	})189	t.Run("ends are different 2", func(t *testing.T) {190		a := NewArrayStream([]string{"a", "c", "d", "f", "g"})191		b := NewArrayStream([]string{"b", "c", "d", "e"})192		c := Xor(a, b)193		assert.Equal(t, consume(t, c), []string{"a", "b", "e", "f", "g"})194	})195	t.Run("middle are different 1", func(t *testing.T) {196		a := NewArrayStream([]string{"a", "c", "d", "f"})197		b := NewArrayStream([]string{"a", "b", "e", "f"})198		c := Xor(a, b)199		assert.Equal(t, consume(t, c), []string{"b", "c", "d", "e"})200	})201	t.Run("closes underlying streams", func(t *testing.T) {202		a := &streamCloserTester{203			stream: EmptyStream(),204		}205		b := &streamCloserTester{206			stream: EmptyStream(),207		}208		c := Xor(a, b)209		require.NoError(t, c.Close())210		require.NoError(t, c.Close())211		assert.Equal(t, 1, a.called)212		assert.Equal(t, 1, b.called)213	})214}215func TestSub(t *testing.T) {216	t.Run("no overlap 1", func(t *testing.T) {217		a := NewArrayStream([]string{"a", "b", "c"})218		b := NewArrayStream([]string{"d", "e"})219		c := Sub(a, b)220		assert.Equal(t, consume(t, c), []string{"a", "b", "c"})221	})222	t.Run("no overlap 1", func(t *testing.T) {223		a := NewArrayStream([]string{"b", "c", "d"})224		b := NewArrayStream([]string{"a", "e"})225		c := Sub(a, b)226		assert.Equal(t, consume(t, c), []string{"b", "c", "d"})227	})228	t.Run("no overlap 2", func(t *testing.T) {229		a := NewArrayStream([]string{"x", "y", "z"})230		b := NewArrayStream([]string{"a", "e"})231		c := Sub(a, b)232		assert.Equal(t, consume(t, c), []string{"x", "y", "z"})233	})234	t.Run("edge overlap", func(t *testing.T) {235		a := NewArrayStream([]string{"a", "b", "c"})236		b := NewArrayStream([]string{"a", "c"})237		c := Sub(a, b)238		assert.Equal(t, consume(t, c), []string{"b"})239	})240	t.Run("middle overlap 1", func(t *testing.T) {241		a := NewArrayStream([]string{"a", "b", "c", "d"})242		b := NewArrayStream([]string{"b", "e"})243		c := Sub(a, b)244		assert.Equal(t, consume(t, c), []string{"a", "c", "d"})245	})246	t.Run("middle overlap 2", func(t *testing.T) {247		a := NewArrayStream([]string{"a", "b", "c", "d"})248		b := NewArrayStream([]string{"b", "c"})249		c := Sub(a, b)250		assert.Equal(t, consume(t, c), []string{"a", "d"})251	})252	t.Run("long a 1", func(t *testing.T) {253		a := NewArrayStream([]string{"a", "b", "c", "d"})254		b := NewArrayStream([]string{"a"})255		c := Sub(a, b)256		assert.Equal(t, consume(t, c), []string{"b", "c", "d"})257	})258	t.Run("long a 2", func(t *testing.T) {259		a := NewArrayStream([]string{"a", "b", "c", "d"})260		b := NewArrayStream([]string{"d"})261		c := Sub(a, b)262		assert.Equal(t, consume(t, c), []string{"a", "b", "c"})263	})264	t.Run("long a 3", func(t *testing.T) {265		a := NewArrayStream([]string{"a", "b", "c", "d"})266		b := NewArrayStream([]string{"z"})267		c := Sub(a, b)268		assert.Equal(t, consume(t, c), []string{"a", "b", "c", "d"})269	})270	t.Run("long b 1", func(t *testing.T) {271		a := NewArrayStream([]string{"a"})272		b := NewArrayStream([]string{"a", "b", "c", "d"})273		c := Sub(a, b)274		assert.Equal(t, consume(t, c), []string{})275	})276	t.Run("long b 2", func(t *testing.T) {277		a := NewArrayStream([]string{"a"})278		b := NewArrayStream([]string{"b", "c", "d"})279		c := Sub(a, b)280		assert.Equal(t, consume(t, c), []string{"a"})281	})282	t.Run("closes underlying streams", func(t *testing.T) {283		a := &streamCloserTester{284			stream: EmptyStream(),285		}286		b := &streamCloserTester{287			stream: EmptyStream(),288		}289		c := Sub(a, b)290		require.NoError(t, c.Close())291		require.NoError(t, c.Close())292		assert.Equal(t, 1, a.called)293		assert.Equal(t, 1, b.called)294	})295}296func TestMerge(t *testing.T) {297	t.Run("no streams", func(t *testing.T) {298		assert.Equal(t, []string{}, consume(t, Merge()))299	})300	t.Run("one stream", func(t *testing.T) {301		a := NewArrayStream([]string{"a", "b", "c"})302		b := Merge(a)303		assert.Equal(t, []string{"a", "b", "c"}, consume(t, b))304	})305	t.Run("empty a", func(t *testing.T) {306		a := NewArrayStream([]string{"a", "b", "c"})307		b := NewArrayStream([]string{})308		c := Merge(a, b)309		assert.Equal(t, []string{"a", "b", "c"}, consume(t, c))310	})311	t.Run("empty b", func(t *testing.T) {312		a := NewArrayStream([]string{"a", "b", "c"})313		b := NewArrayStream([]string{})314		c := Merge(a, b)315		assert.Equal(t, []string{"a", "b", "c"}, consume(t, c))316	})317	t.Run("no overlap 1", func(t *testing.T) {318		a := NewArrayStream([]string{"a", "c"})319		b := NewArrayStream([]string{"b", "d", "e"})320		c := Merge(a, b)321		assert.Equal(t, []string{"a", "b", "c", "d", "e"}, consume(t, c))322	})323	t.Run("no overlap 2", func(t *testing.T) {324		a := NewArrayStream([]string{"x", "y"})325		b := NewArrayStream([]string{"a", "b", "c"})326		c := Merge(a, b)327		assert.Equal(t, []string{"a", "b", "c", "x", "y"}, consume(t, c))328	})329	t.Run("full overlap", func(t *testing.T) {330		a := NewArrayStream([]string{"a", "b", "c"})331		b := NewArrayStream([]string{"a", "b", "c"})332		c := Merge(a, b)333		assert.Equal(t, []string{"a", "b", "c"}, consume(t, c))334	})335	t.Run("overlap 1", func(t *testing.T) {336		a := NewArrayStream([]string{"a", "b", "c", "d"})337		b := NewArrayStream([]string{"a", "b", "c"})338		c := Merge(a, b)339		assert.Equal(t, []string{"a", "b", "c", "d"}, consume(t, c))340	})341	t.Run("overlap 2", func(t *testing.T) {342		a := NewArrayStream([]string{"a", "b", "c", "d", "z"})343		b := NewArrayStream([]string{"a", "b", "c", "x", "y"})344		c := Merge(a, b)345		assert.Equal(t, []string{"a", "b", "c", "d", "x", "y", "z"}, consume(t, c))346	})347	t.Run("overlap 3", func(t *testing.T) {348		a := NewArrayStream([]string{"a", "b", "c", "d", "y"})349		b := NewArrayStream([]string{"a", "b", "c", "x", "y", "z"})350		c := Merge(a, b)351		assert.Equal(t, []string{"a", "b", "c", "d", "x", "y", "z"}, consume(t, c))352	})353}354func TestMerge3Streams(t *testing.T) {355	t.Run("overlap 1", func(t *testing.T) {356		a := NewArrayStream([]string{"a", "b", "c", "d"})357		b := NewArrayStream([]string{"a", "b", "c"})358		c := NewArrayStream([]string{"a", "x", "y", "z"})359		d := Merge(a, b, c)360		assert.Equal(t, []string{"a", "b", "c", "d", "x", "y", "z"}, consume(t, d))361	})362	t.Run("overlap 2", func(t *testing.T) {363		a := NewArrayStream([]string{"a", "b", "c", "d"})364		b := NewArrayStream([]string{"a", "b", "c"})365		c := NewArrayStream([]string{"a", "b", "c", "d", "x", "y", "z"})366		d := Merge(a, b, c)367		assert.Equal(t, []string{"a", "b", "c", "d", "x", "y", "z"}, consume(t, d))368	})369	t.Run("no overlap 1", func(t *testing.T) {370		a := NewArrayStream([]string{"a", "b", "c", "f"})371		b := NewArrayStream([]string{"d", "e", "j", "k"})372		c := NewArrayStream([]string{"g", "h", "i", "l"})373		d := Merge(a, b, c)374		assert.Equal(t, []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"}, consume(t, d))375	})376	t.Run("closes underlying streams 2", func(t *testing.T) {377		a := &streamCloserTester{378			stream: EmptyStream(),379		}380		b := &streamCloserTester{381			stream: EmptyStream(),382		}383		c := Merge(a, b)384		require.NoError(t, c.Close())385		require.NoError(t, c.Close())386		assert.Equal(t, 1, a.called)387		assert.Equal(t, 1, b.called)388	})389	t.Run("closes underlying streams 3", func(t *testing.T) {390		a := &streamCloserTester{391			stream: EmptyStream(),392		}393		b := &streamCloserTester{394			stream: EmptyStream(),395		}396		c := &streamCloserTester{397			stream: EmptyStream(),398		}399		d := Merge(a, b, c)400		require.NoError(t, d.Close())401		require.NoError(t, d.Close())402		assert.Equal(t, 1, a.called)403		assert.Equal(t, 1, b.called)404		assert.Equal(t, 1, c.called)405	})406}407// TestReplayableStream tests that the replayable stream is replayable and that408// it cleans up the underlying streams and files it uses.409func TestReplayableStream(t *testing.T) {410	t.Run("replayable if reset", func(t *testing.T) {411		contents := []string{"a", "b", "c"}412		r, err := NewReplayableStream(NewArrayStream(contents))413		require.NoError(t, err)414		// Consume, verify, reset, repeat415		require.Equal(t, contents, consume(t, r))416		require.NoError(t, r.Reset())417		require.Equal(t, contents, consume(t, r))418		require.NoError(t, r.Reset())419		require.Equal(t, contents, consume(t, r))420		// Make sure it throws an error when we try to consume it without a reset421		_, err = r.Next()422		require.Error(t, err)423		// Can close twice without error424		require.NoError(t, r.Close())425		require.NoError(t, r.Close())426	})427	t.Run("closes underlying stream", func(t *testing.T) {428		a := &streamCloserTester{429			stream: EmptyStream(),430		}431		r, err := NewReplayableStream(a)432		require.NoError(t, err)433		require.NoError(t, r.Close())434		require.Equal(t, 1, a.called)435	})436	t.Run("closes reader stream and cleans up replay file", func(t *testing.T) {437		contents := []string{"a", "b", "c"}438		a := &streamCloserTester{439			stream: NewArrayStream(contents),440		}441		// Manually compose the replay stream so that we can verify it closes things442		replayFile, err := ioutil.TempFile("", "replay-test")443		require.NoError(t, err)444		r := &replayableStream{445			replayFile:  replayFile,446			writeStream: NewLoggingStream(a, replayFile),447		}448		consume(t, r)449		require.NoError(t, r.Close())450		require.Equal(t, 1, a.called)451		_, err = os.Stat(replayFile.Name())452		require.True(t, os.IsNotExist(err))453	})454	t.Run("always consumes source stream entirely before replay", func(t *testing.T) {455		contents := []string{"a", "b", "c"}456		r, err := NewReplayableStream(NewArrayStream(contents))457		require.NoError(t, err)458		// Consume some, reset, consume all and expect replay to have all459		res, err := r.Next()460		require.NoError(t, err)461		require.Equal(t, "a", res)462		res, err = r.Next()463		require.NoError(t, err)...

Full Screen

Full Screen

helper.go

Source:helper.go Github

copy

Full Screen

1package main2import (3	"context"4	"time"5	"github.com/golang/protobuf/ptypes"6	"github.com/golang/protobuf/ptypes/timestamp"7	_ "github.com/lib/pq"8	account "onepass.app/facility/hts/account"9	common "onepass.app/facility/hts/common"10	facility "onepass.app/facility/hts/facility"11	organizer "onepass.app/facility/hts/organizer"12	participant "onepass.app/facility/hts/participant"13	"onepass.app/facility/internal/helper"14	typing "onepass.app/facility/internal/typing"15)16// hasPermission is mock function for account.hasPermission17func hasPermission(accountClient account.AccountServiceClient, userID int64, organizationID int64, permissionName common.Permission) (bool, typing.CustomError) {18	in := account.HasPermissionRequest{19		OrganizationId: organizationID,20		UserId:         userID,21		PermissionName: permissionName,22	}23	result, err := accountClient.HasPermission(context.Background(), &in)24	if err != nil {25		return false, &typing.GRPCError{Name: "Account service"}26	}27	return result.IsOk, nil28}29// hasEvent is mock function for organization.hasEvent30func hasEvent(oragnizationClient organizer.OrganizationServiceClient, organizationID int64, userID int64, eventID int64) (bool, typing.CustomError) {31	in := organizer.HasEventReq{32		OrganizationId: organizationID,33		UserId:         userID,34		EventId:        eventID,35	}36	result, err := oragnizationClient.HasEvent(context.Background(), &in)37	if err != nil {38		return false, &typing.GRPCError{Name: "Organization service"}39	}40	return result.IsOk, nil41}42// getEvent is mock function for Participant.getEvent43func getEvent(participantClient participant.ParticipantServiceClient, eventID int64) (*common.Event, typing.CustomError) {44	in := participant.GetEventRequest{45		EventId: eventID,46	}47	result, err := participantClient.GetEvent(context.Background(), &in)48	if err != nil {49		return nil, &typing.GRPCError{Name: "Participant service"}50	}51	return result, nil52}53// isAbleToCreateFacilityRequest is function to check if a facility is able to book according to user psermission54func isAbleToCreateFacilityRequest(fs *FacilityServer, in *facility.CreateFacilityRequestRequest) (bool, typing.CustomError) {55	havingPermissionChannel := make(chan bool)56	eventOwnerChannel := make(chan bool)57	overlapTimeChannel := make(chan bool)58	errorChannel := make(chan typing.CustomError)59	go func() {60		isTimeOverlap, err := fs.dbs.IsOverlapTime(in.FacilityId, in.Start, in.End, true)61		errorChannel <- err62		overlapTimeChannel <- isTimeOverlap63	}()64	event, err := getEvent(fs.participant, in.EventId)65	if err != nil {66		return false, err67	}68	go func() {69		result, err := hasPermission(fs.account, in.UserId, event.OrganizationId, common.Permission_UPDATE_EVENT)70		if err != nil {71			errorChannel <- err72			havingPermissionChannel <- false73			return74		}75		havingPermissionChannel <- result76	}()77	go func() {78		result, err := hasEvent(fs.organizer, in.UserId, event.OrganizationId, in.EventId)79		if err != nil {80			errorChannel <- err81			eventOwnerChannel <- false82			return83		}84		eventOwnerChannel <- result85	}()86	isPermission := <-havingPermissionChannel87	isTimeOverlap := <-overlapTimeChannel88	isEventOwner := <-eventOwnerChannel89	close(errorChannel)90	for err := range errorChannel {91		return false, err92	}93	close(havingPermissionChannel)94	close(eventOwnerChannel)95	close(overlapTimeChannel)96	close(errorChannel)97	if !(isPermission && isEventOwner) {98		return false, &typing.PermissionError{Type: common.Permission_UPDATE_EVENT}99	}100	if isTimeOverlap {101		return false, &typing.AlreadyExistError{Name: "Facility is booked at that time"}102	}103	return true, nil104}105// isAbleToApproveFacilityRequest is function to check if a facility is able to be approved according to user psermission106func isAbleToApproveFacilityRequest(fs *FacilityServer, in *facility.ApproveFacilityRequestRequest) (bool, typing.CustomError) {107	facilityRequest, err := fs.dbs.GetFacilityRequest(in.RequestId)108	if err != nil {109		return false, err110	}111	havingPermissionChannel := make(chan bool)112	overlapTimeChannel := make(chan bool)113	errorChannel := make(chan typing.CustomError, 2)114	go func() {115		facility, err := fs.dbs.GetFacilityInfo(facilityRequest.FacilityId)116		if err != nil {117			errorChannel <- err118			havingPermissionChannel <- false119			return120		}121		result, err := hasPermission(fs.account, in.UserId, facility.OrganizationId, common.Permission_UPDATE_FACILITY)122		if err != nil {123			errorChannel <- err124			havingPermissionChannel <- false125			return126		}127		havingPermissionChannel <- result128	}()129	go func() {130		isTimeOverlap, err := fs.dbs.IsOverlapTime(facilityRequest.FacilityId, facilityRequest.Start, facilityRequest.Finish, false)131		if err != nil {132			errorChannel <- err133			overlapTimeChannel <- true134			return135		}136		overlapTimeChannel <- isTimeOverlap137	}()138	isPermission := <-havingPermissionChannel139	isTimeOverlap := <-overlapTimeChannel140	close(errorChannel)141	for err := range errorChannel {142		return false, err143	}144	close(overlapTimeChannel)145	close(havingPermissionChannel)146	if !isPermission {147		return false, &typing.PermissionError{Type: common.Permission_UPDATE_FACILITY}148	}149	if isTimeOverlap {150		return false, &typing.AlreadyExistError{Name: "Facility is booked at that time"}151	}152	return true, nil153}154// isAbleToRejectFacilityRequest is function to check if a facility is able to be rejected according to user psermission155func isAbleToRejectFacilityRequest(fs *FacilityServer, in *facility.RejectFacilityRequestRequest) (bool, typing.CustomError) {156	facilityRequest, err := fs.dbs.GetFacilityRequest(in.RequestId)157	if err != nil {158		return false, err159	}160	facility, err := fs.dbs.GetFacilityInfo(facilityRequest.FacilityId)161	if err != nil {162		return false, err163	}164	isPermission, err := hasPermission(fs.account, in.UserId, facility.OrganizationId, common.Permission_UPDATE_FACILITY)165	if err != nil {166		return false, err167	}168	if !isPermission {169		return false, &typing.PermissionError{Type: common.Permission_UPDATE_FACILITY}170	}171	return true, nil172}173func handlePermissionChannel(permissionEventChannel <-chan bool, permissionFacilityChannel <-chan bool) (bool, common.Permission, typing.CustomError) {174	var isPermissionEvent bool175	for i := 0; i < 2; i++ {176		select {177		case isPermissionEvent := <-permissionEventChannel:178			if isPermissionEvent {179				return true, 0, nil180			}181		case isPermissionFacility := <-permissionFacilityChannel:182			if isPermissionFacility {183				return true, 0, nil184			}185		}186	}187	if !isPermissionEvent {188		return false, common.Permission_UPDATE_EVENT, nil189	}190	return false, common.Permission_UPDATE_FACILITY, nil191}192// isAbleToViewFacilityRequest a function to check whether user can view the targed facility request193func isAbleToViewFacilityRequest(fs *FacilityServer, userID int64, facilityRequest *common.FacilityRequest) (bool, common.Permission, typing.CustomError) {194	facility, err := fs.dbs.GetFacilityInfo(facilityRequest.FacilityId)195	if err != nil {196		return false, 0, err197	}198	permissionEventChannel := make(chan bool)199	permissionFacilityChannel := make(chan bool)200	errorChannel := make(chan typing.CustomError)201	go func() {202		event, err := getEvent(fs.participant, facilityRequest.EventId)203		if err != nil {204			errorChannel <- err205			permissionEventChannel <- false206			return207		}208		result, err := hasPermission(fs.account, userID, event.OrganizationId, common.Permission_UPDATE_EVENT)209		if err != nil {210			errorChannel <- err211			permissionEventChannel <- false212			return213		}214		permissionEventChannel <- result215	}()216	go func() {217		result, err := hasPermission(fs.account, userID, facility.OrganizationId, common.Permission_UPDATE_FACILITY)218		if err != nil {219			errorChannel <- err220			permissionFacilityChannel <- false221			return222		}223		permissionFacilityChannel <- result224	}()225	result, permission, err := handlePermissionChannel(permissionEventChannel, permissionFacilityChannel)226	close(errorChannel)227	for err := range errorChannel {228		return false, 0, err229	}230	return result, permission, err231}232// isAbleToViewFacilityRequestFull a function to check whether user can view the targed facility request233func isAbleToViewFacilityRequestFull(fs *FacilityServer, userID int64, facilityRequestFull *facility.FacilityRequestWithFacilityInfo) (bool, common.Permission, typing.CustomError) {234	event, err := getEvent(fs.participant, facilityRequestFull.EventId)235	for err != nil {236		return false, 0, err237	}238	permissionEventChannel := make(chan bool)239	permissionFacilityChannel := make(chan bool)240	errorChannel := make(chan typing.CustomError)241	go func() {242		result, err := hasPermission(fs.account, userID, event.OrganizationId, common.Permission_UPDATE_EVENT)243		if err != nil {244			errorChannel <- err245			permissionEventChannel <- false246			return247		}248		permissionEventChannel <- result249	}()250	go func() {251		result, err := hasPermission(fs.account, userID, facilityRequestFull.OrganizationId, common.Permission_UPDATE_FACILITY)252		if err != nil {253			errorChannel <- err254			permissionFacilityChannel <- false255			return256		}257		permissionFacilityChannel <- result258	}()259	result, permission, err := handlePermissionChannel(permissionEventChannel, permissionFacilityChannel)260	close(errorChannel)261	for err := range errorChannel {262		return false, 0, err263	}264	return result, permission, err265}266// isAbleToGetAvailableTimeOfFacility a function to check whether user can check facility availability267func isAbleToGetAvailableTimeOfFacility(startTime time.Time, finishTime time.Time) typing.CustomError {268	if helper.DayDifference(startTime, finishTime)+1 <= 0 {269		return &typing.InputError{Name: "Start must be earlier than Finish"}270	}271	now := time.Now()272	if helper.DayDifference(now, finishTime) >= 30 {273		return &typing.InputError{Name: "Booking date can only be within 30 days period from today"}274	}275	dayDifference := helper.DayDifference(now, startTime)276	if dayDifference < 0 {277		return &typing.InputError{Name: "Booking time must not be in the past"}278	}279	return nil280}281// createResultEmptyArray is function to create 2D empy boolean array according to input282func createResultEmptyArray(startTime time.Time, finishTime time.Time, operatingHours map[int32]*common.OperatingHour) []*facility.GetAvailableTimeOfFacilityResponse_Day {283	dayDifference := helper.DayDifference(startTime, finishTime) + 1284	result := make([]*facility.GetAvailableTimeOfFacilityResponse_Day, dayDifference)285	var currentDay time.Time286	for i := range result {287		currentDay = startTime.AddDate(0, 0, i)288		operationHour := operatingHours[int32(currentDay.Weekday())]289		if operationHour == nil {290			result[i] = &facility.GetAvailableTimeOfFacilityResponse_Day{Items: nil}291			continue292		}293		startHour := operationHour.StartHour294		finishHour := operationHour.FinishHour295		hour := finishHour - startHour296		avaialbleTime := make([]bool, hour)297		for j := range avaialbleTime {298			avaialbleTime[j] = true299		}300		result[i] = &facility.GetAvailableTimeOfFacilityResponse_Day{Items: avaialbleTime}301	}302	return result303}304// generateFacilityAvailabilityResult is a function to genereate facility request from empty 2D boolean array305func generateFacilityAvailabilityResult(resultArray []*facility.GetAvailableTimeOfFacilityResponse_Day, startTime time.Time, operatingHours map[int32]*common.OperatingHour, facilityRequests []*common.FacilityRequest) *facility.GetAvailableTimeOfFacilityResponse {306	for _, request := range facilityRequests {307		requestStartTime, _ := ptypes.Timestamp(request.Start)308		requestFinishTime, _ := ptypes.Timestamp(request.Finish)309		index := requestStartTime.Day() - startTime.Day()310		operatiingHour := operatingHours[int32(requestStartTime.Weekday())]311		if operatiingHour == nil {312			continue313		}314		startHour := operatiingHour.StartHour315		requestStartHour := requestStartTime.Hour()316		requestFinishHour := requestFinishTime.Hour()317		for i, item := range resultArray[index].Items {318			currentHour := int(startHour) + i319			if item && currentHour <= requestStartHour || currentHour >= requestFinishHour {320				resultArray[index].Items[i] = false321			}322		}323	}324	return &facility.GetAvailableTimeOfFacilityResponse{Day: resultArray}325}326// getFacilityInfoWithRequests is function to preapare facility info for GetAvailableTimeOfFacility API327func getFacilityInfoWithRequests(fs *FacilityServer, facilityID int64, start *timestamp.Timestamp, end *timestamp.Timestamp) (*FacilityInfoWithRequest, typing.CustomError) {328	errorChannel := make(chan typing.CustomError, 2)329	faicilityInfoChannel := make(chan *common.Facility)330	faiclityRequestsChannel := make(chan []*common.FacilityRequest)331	go func() {332		facilityInfo, err := fs.dbs.GetFacilityInfo(facilityID)333		if err != nil {334			errorChannel <- err335		}336		faicilityInfoChannel <- facilityInfo337	}()338	go func() {339		facilityRequests, err := fs.dbs.GetApprovedFacilityRequestList(facilityID, start, end)340		if err != nil {341			errorChannel <- err342		}343		faiclityRequestsChannel <- facilityRequests344	}()345	facilityInfo := <-faicilityInfoChannel346	facilityRequests := <-faiclityRequestsChannel347	close(errorChannel)348	for err := range errorChannel {349		return nil, err350	}351	close(faicilityInfoChannel)352	close(faiclityRequestsChannel)353	return &FacilityInfoWithRequest{Info: facilityInfo, Requests: facilityRequests}, nil354}...

Full Screen

Full Screen

fuzzyfiles.go

Source:fuzzyfiles.go Github

copy

Full Screen

1package main2import (3	"fmt"4	"os"5	"os/signal"6	"strings"7	"sync"8)9func inList(item string, list []string) bool {10	for _, v := range list {11		if strings.ToLower(v) == strings.ToLower(item) {12			return true13		}14	}15	return false16}17const EXCLUDEZEROBYTE = true18const EXCLUDEHELLO = true19func GetAllFiles(pattern string, pathfilter []string) map[string]DiskCatalog {20	cache := make(map[string]DiskCatalog)21	exists, matches := existsPattern(*baseName, pathfilter, pattern)22	if !exists {23		return cache24	}25	workchan := make(chan string, 100)26	var s sync.Mutex27	var wg sync.WaitGroup28	for i := 0; i < ingestWorkers; i++ {29		wg.Add(1)30		go func() {31			for m := range workchan {32				item := &Disk{}33				if err := item.ReadFromFile(m); err == nil {34					if len(item.Files) == 0 {35						continue36					}37					// Load cache38					s.Lock()39					cache[item.FullPath] = item.Files40					s.Unlock()41				} else {42					fmt.Println("FAIL")43				}44			}45			wg.Done()46		}()47	}48	var lastPc int = -149	for i, m := range matches {50		//fmt.Printf("Queue: %s\n", m)51		workchan <- m52		pc := int(100 * float64(i) / float64(len(matches)))53		if pc != lastPc {54			fmt.Print("\r")55			os.Stderr.WriteString(fmt.Sprintf("Caching data... %d%%   ", pc))56		}57		lastPc = pc58	}59	close(workchan)60	wg.Wait()61	return cache62}63type FileOverlapRecord struct {64	files   map[string]map[*DiskFile]*DiskFile65	percent map[string]float6466	missing map[string][]*DiskFile67	extras  map[string][]*DiskFile68}69func (f *FileOverlapRecord) Remove(key string) {70	delete(f.files, key)71	delete(f.percent, key)72	delete(f.missing, key)73	delete(f.extras, key)74}75func (f *FileOverlapRecord) IsSubsetOf(filename string) bool {76	// f is a subset if:77	// missing == 078	// extra > 079	if _, ok := f.files[filename]; !ok {80		return false81	}82	return len(f.extras[filename]) > 0 && len(f.missing[filename]) == 083}84func (f *FileOverlapRecord) IsSupersetOf(filename string) bool {85	// f is a superset if:86	// missing > 087	// extra == 088	if _, ok := f.files[filename]; !ok {89		return false90	}91	return len(f.extras[filename]) == 0 && len(f.missing[filename]) > 092}93// Actual fuzzy file match report94func CollectFilesOverlapsAboveThreshold(t float64, pathfilter []string) map[string]*FileOverlapRecord {95	filerecords := GetAllFiles("*_*_*_*.fgp", pathfilter)96	results := make(map[string]*FileOverlapRecord)97	workchan := make(chan string, 100)98	var wg sync.WaitGroup99	var s sync.Mutex100	c := make(chan os.Signal, 1)101	signal.Notify(c, os.Interrupt)102	for i := 0; i < processWorkers; i++ {103		wg.Add(1)104		go func() {105			for m := range workchan {106				v := &FileOverlapRecord{107					files:   make(map[string]map[*DiskFile]*DiskFile),108					percent: make(map[string]float64),109					missing: make(map[string][]*DiskFile),110					extras:  make(map[string][]*DiskFile),111				}112				d := filerecords[m]113				for k, b := range filerecords {114					if k == m {115						continue // dont compare ourselves116					}117					// ok good to compare -- only keep if we need our threshold118					if closeness := CompareCatalogs(d, b, v, k); closeness < t {119						v.Remove(k)120					} else {121						v.percent[k] = closeness122					}123				}124				// since we delete < threshold, only add if we have any result125				if len(v.percent) > 0 {126					//os.Stderr.WriteString("\r\nAdded file: " + m + "\r\n\r\n")127					s.Lock()128					results[m] = v129					s.Unlock()130				}131			}132			wg.Done()133		}()134	}135	// feed data in136	var lastPc int = -1137	var i int138	for k, _ := range filerecords {139		if len(c) > 0 {140			sig := <-c141			if sig == os.Interrupt {142				close(c)143				os.Stderr.WriteString("\r\nInterrupted. Waiting for workers to stop.\r\n\r\n")144				break145			}146		}147		workchan <- k148		pc := int(100 * float64(i) / float64(len(filerecords)))149		if pc != lastPc {150			fmt.Print("\r")151			os.Stderr.WriteString(fmt.Sprintf("Processing files data... %d%%   ", pc))152		}153		lastPc = pc154		i++155	}156	close(workchan)157	wg.Wait()158	return results159}160func GetCatalogMap(d DiskCatalog) map[string]*DiskFile {161	out := make(map[string]*DiskFile)162	for _, v := range d {163		out[v.SHA256] = v164	}165	return out166}167func CompareCatalogs(d, b DiskCatalog, r *FileOverlapRecord, key string) float64 {168	var sameFiles float64169	var missingFiles float64170	var extraFiles float64171	var dmap = GetCatalogMap(d)172	var bmap = GetCatalogMap(b)173	for fileCk, info := range dmap {174		if info.Size == 0 && EXCLUDEZEROBYTE {175			continue176		}177		if info.Filename == "hello" && EXCLUDEHELLO {178			continue179		}180		binfo, bEx := bmap[fileCk]181		if bEx {182			sameFiles += 1183			// file match184			if r.files[key] == nil {185				r.files[key] = make(map[*DiskFile]*DiskFile)186			}187			//fmt.Printf("*** %s: %s -> %s\n", b.Filename, binfo.Filename, info.Filename)188			r.files[key][binfo] = info189		} else {190			missingFiles += 1191			// file match192			if r.missing[key] == nil {193				r.missing[key] = make([]*DiskFile, 0)194			}195			//fmt.Printf("*** %s: %s -> %s\n", b.Filename, binfo.Filename, info.Filename)196			r.missing[key] = append(r.missing[key], info)197		}198	}199	for fileCk, info := range bmap {200		if info.Size == 0 {201			continue202		}203		_, dEx := dmap[fileCk]204		if !dEx {205			extraFiles += 1206			// file match207			if r.extras[key] == nil {208				r.extras[key] = make([]*DiskFile, 0)209			}210			//fmt.Printf("*** %s: %s -> %s\n", b.Filename, binfo.Filename, info.Filename)211			r.extras[key] = append(r.extras[key], info)212		}213	}214	if (sameFiles + extraFiles + missingFiles) == 0 {215		return 0216	}217	// return sameSectors / dTotal, sameSectors / bTotal, diffSectors / dTotal, diffSectors / btotal218	return sameFiles / (sameFiles + extraFiles + missingFiles)219}220func CollectFileSubsets(pathfilter []string) map[string]*FileOverlapRecord {221	filerecords := GetAllFiles("*_*_*_*.fgp", pathfilter)222	results := make(map[string]*FileOverlapRecord)223	workchan := make(chan string, 100)224	var wg sync.WaitGroup225	var s sync.Mutex226	c := make(chan os.Signal, 1)227	signal.Notify(c, os.Interrupt)228	for i := 0; i < processWorkers; i++ {229		wg.Add(1)230		go func() {231			for m := range workchan {232				v := &FileOverlapRecord{233					files:   make(map[string]map[*DiskFile]*DiskFile),234					percent: make(map[string]float64),235					missing: make(map[string][]*DiskFile),236					extras:  make(map[string][]*DiskFile),237				}238				d := filerecords[m]239				for k, b := range filerecords {240					if k == m {241						continue // dont compare ourselves242					}243					// ok good to compare -- only keep if we need our threshold244					closeness := CompareCatalogs(d, b, v, k)245					if !v.IsSubsetOf(k) {246						v.Remove(k)247					} else {248						v.percent[k] = closeness249					}250				}251				// since we delete < threshold, only add if we have any result252				if len(v.percent) > 0 {253					//os.Stderr.WriteString("\r\nAdded file: " + m + "\r\n\r\n")254					s.Lock()255					results[m] = v256					s.Unlock()257				}258			}259			wg.Done()260		}()261	}262	// feed data in263	var lastPc int = -1264	var i int265	for k, _ := range filerecords {266		if len(c) > 0 {267			sig := <-c268			if sig == os.Interrupt {269				close(c)270				os.Stderr.WriteString("\r\nInterrupted. Waiting for workers to stop.\r\n\r\n")271				break272			}273		}274		workchan <- k275		pc := int(100 * float64(i) / float64(len(filerecords)))276		if pc != lastPc {277			fmt.Print("\r")278			os.Stderr.WriteString(fmt.Sprintf("Processing files data... %d%%   ", pc))279		}280		lastPc = pc281		i++282	}283	close(workchan)284	wg.Wait()285	return results286}287func CollectFilesOverlapsCustom(keep func(d1, d2 string, v *FileOverlapRecord) bool, pathfilter []string) map[string]*FileOverlapRecord {288	filerecords := GetAllFiles("*_*_*_*.fgp", pathfilter)289	results := make(map[string]*FileOverlapRecord)290	workchan := make(chan string, 100)291	var wg sync.WaitGroup292	var s sync.Mutex293	c := make(chan os.Signal, 1)294	signal.Notify(c, os.Interrupt)295	for i := 0; i < processWorkers; i++ {296		wg.Add(1)297		go func() {298			for m := range workchan {299				v := &FileOverlapRecord{300					files:   make(map[string]map[*DiskFile]*DiskFile),301					percent: make(map[string]float64),302					missing: make(map[string][]*DiskFile),303					extras:  make(map[string][]*DiskFile),304				}305				d := filerecords[m]306				for k, b := range filerecords {307					if k == m {308						continue // dont compare ourselves309					}310					// ok good to compare -- only keep if we need our threshold311					closeness := CompareCatalogs(d, b, v, k)312					if !keep(m, k, v) {313						v.Remove(k)314					} else {315						v.percent[k] = closeness316					}317				}318				// since we delete < threshold, only add if we have any result319				if len(v.files) > 0 {320					//os.Stderr.WriteString("\r\nAdded file: " + m + "\r\n\r\n")321					s.Lock()322					results[m] = v323					s.Unlock()324				}325			}326			wg.Done()327		}()328	}329	// feed data in330	var lastPc int = -1331	var i int332	for k, _ := range filerecords {333		if len(c) > 0 {334			sig := <-c335			if sig == os.Interrupt {336				close(c)337				os.Stderr.WriteString("\r\nInterrupted. Waiting for workers to stop.\r\n\r\n")338				break339			}340		}341		workchan <- k342		pc := int(100 * float64(i) / float64(len(filerecords)))343		if pc != lastPc {344			fmt.Print("\r")345			os.Stderr.WriteString(fmt.Sprintf("Processing files data... %d%%   ", pc))346		}347		lastPc = pc348		i++349	}350	close(workchan)351	wg.Wait()352	return results353}...

Full Screen

Full Screen

digraph.go

Source:digraph.go Github

copy

Full Screen

...205func (g *Digraph) TooLarge(node lattice.Node) bool {206	V, E := VE(node)207	return E > g.MaxEdges || V > g.MaxVertices208}209func (g *Digraph) Close() error {210	g.lock.Lock()211	defer g.lock.Unlock()212	g.config.AsyncTasks.Wait()213	g.Parents.Close()214	g.ParentCount.Close()215	g.Children.Close()216	g.ChildCount.Close()217	g.CanonKids.Close()218	g.CanonKidCount.Close()219	g.Embeddings.Close()220	if g.Overlap != nil {221		g.Overlap.Close()222	}223	g.Extensions.Close()224	if g.UnsupExts != nil {225		g.UnsupExts.Close()226	}227	g.NodeAttrs.Close()228	g.Frequency.Close()229	return nil230}...

Full Screen

Full Screen

Close

Using AI Code Generation

copy

Full Screen

1func main() {2  o.Close()3}4func main() {5  o.Close()6}7func main() {8  o.Close()9}10func main() {11  o.Close()12}13func main() {14  o.Close()15}16func main() {17  o.Close()18}19func main() {20  o.Close()21}22func main() {23  o.Close()24}25func main() {26  o.Close()27}28func main() {29  o.Close()30}31func main() {32  o.Close()33}34func main() {35  o.Close()36}37func main() {38  o.Close()39}40func main() {41  o.Close()42}43func main() {44  o.Close()45}46func main()

Full Screen

Full Screen

Close

Using AI Code Generation

copy

Full Screen

1import "fmt"2type Overlap struct {3}4func (o *Overlap) Close() {5    fmt.Println("Close called")6}7func main() {8    o.Close()9}10import "fmt"11type Overlap struct {12}13func (o *Overlap) Close() {14    fmt.Println("Close called")15}16func main() {17    (&o).Close()18}19import "fmt"20type Overlap struct {21}22func (o *Overlap) Close() {23    fmt.Println("Close called")24}25func (o Overlap) Closed() {26    fmt.Println("Closed called")27}28func main() {29    o.Close()30    o.Closed()31}

Full Screen

Full Screen

Close

Using AI Code Generation

copy

Full Screen

1import "fmt"2type Overlap struct {3}4func (o *Overlap) Close() {5    fmt.Println("Close called")6}7func main() {8    o := Overlap{10, 20}9    defer o.Close()10    fmt.Println("main ended")11}

Full Screen

Full Screen

Close

Using AI Code Generation

copy

Full Screen

1import "fmt"2func main() {3    fmt.Println("Hello, World!")4    o.Close()5}6import "fmt"7func main() {8    fmt.Println("Hello, World!")9    o.Close()10}11import "fmt"12func main() {13    fmt.Println("Hello, World!")14    o.Close()15}16import "fmt"17func main() {18    fmt.Println("Hello, World!")19    o.Close()20}21import "fmt"22func main() {23    fmt.Println("Hello, World!")24    o.Close()25}26import "fmt"27func main() {28    fmt.Println("Hello, World!")29    o.Close()30}31import "fmt"32func main() {33    fmt.Println("Hello, World!")34    o.Close()35}36import "fmt"37func main() {38    fmt.Println("Hello, World!")39    o.Close()40}41import "fmt"42func main() {43    fmt.Println("Hello, World!")44    o.Close()45}46import "fmt"47func main() {48    fmt.Println("Hello, World!")49    o.Close()50}51import "fmt"52func main() {53    fmt.Println("Hello, World!")54    o.Close()55}

Full Screen

Full Screen

Close

Using AI Code Generation

copy

Full Screen

1import "fmt"2type Overlap struct {3}4func (o *Overlap) Close() {5    fmt.Println("Close method called")6}7func main() {8    o := Overlap{1, 2}9    defer o.Close()10    fmt.Println("main method called")11}

Full Screen

Full Screen

Close

Using AI Code Generation

copy

Full Screen

1import (2func main() {3	fmt.Println("Enter two numbers")4	fmt.Scan(&a, &b)5	c := overlap{a, b}6	c.close()7}8import (9func main() {10	fmt.Println("Enter two numbers")11	fmt.Scan(&a, &b)12	c := overlap{a, b}13	c.close()14}15import (16func main() {17	fmt.Println("Enter two numbers")18	fmt.Scan(&a, &b)19	c := overlap{a, b}20	c.close()21}22import (23func main() {24	fmt.Println("Enter two numbers")25	fmt.Scan(&a, &b)26	c := overlap{a, b}27	c.close()28}29import (30func main() {31	fmt.Println("Enter two numbers")32	fmt.Scan(&a, &b)33	c := overlap{a, b}34	c.close()35}36import (37func main() {38	fmt.Println("Enter two numbers")39	fmt.Scan(&a, &b)40	c := overlap{a, b}41	c.close()42}43import (44func main() {45	fmt.Println("Enter two numbers")46	fmt.Scan(&a, &b)47	c := overlap{a, b}48	c.close()49}50import (51func main() {52	fmt.Println("Enter two numbers")53	fmt.Scan(&a, &b)54	c := overlap{a, b}55	c.close()56}

Full Screen

Full Screen

Close

Using AI Code Generation

copy

Full Screen

1import (2func main() {3	fmt.Println(o.Close())4}5import (6func main() {7	fmt.Println(o.Close())8}9import (10func main() {11	fmt.Println(o.Close())12}13import (14func main() {15	fmt.Println(o.Close())16}17import (18func main() {19	fmt.Println(o.Close())20}21import (22func main() {23	fmt.Println(o.Close())24}25import (26func main() {27	fmt.Println(o.Close())28}29import (30func main() {31	fmt.Println(o.Close())32}33import (34func main() {

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Mock automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful