From 912b126e92507620203046a2fdcd28f24b1e0b70 Mon Sep 17 00:00:00 2001 From: Andrew Dunham Date: Wed, 15 Apr 2015 10:48:50 -0700 Subject: [PATCH] Fix Err fallout for graph/iterator.Materialize iterator --- graph/iterator/materialize_iterator.go | 19 +++++++- graph/iterator/materialize_iterator_test.go | 72 +++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 graph/iterator/materialize_iterator_test.go diff --git a/graph/iterator/materialize_iterator.go b/graph/iterator/materialize_iterator.go index 871df88..2b8a464 100644 --- a/graph/iterator/materialize_iterator.go +++ b/graph/iterator/materialize_iterator.go @@ -48,6 +48,7 @@ type Materialize struct { subIt graph.Iterator hasRun bool aborted bool + err error runstats graph.IteratorStats } @@ -108,6 +109,7 @@ func (it *Materialize) Clone() graph.Iterator { if it.hasRun { out.hasRun = true out.aborted = it.aborted + out.err = it.err out.values = it.values out.containsMap = it.containsMap out.actualSize = it.actualSize @@ -199,8 +201,15 @@ func (it *Materialize) Next() bool { if !it.hasRun { it.materializeSet() } + if it.err != nil { + return false + } if it.aborted { - return graph.Next(it.subIt) + n := graph.Next(it.subIt) + if err := graph.Err(it.subIt); err != nil { + it.err = err + } + return n } it.index++ @@ -211,6 +220,10 @@ func (it *Materialize) Next() bool { return graph.NextLogOut(it, it.Result(), true) } +func (it *Materialize) Err() error { + return it.err +} + func (it *Materialize) Contains(v graph.Value) bool { graph.ContainsLogIn(it, v) it.runstats.Contains += 1 @@ -283,7 +296,9 @@ func (it *Materialize) materializeSet() { it.actualSize += 1 } } - if it.aborted { + if err := graph.Err(it.subIt); err != nil { + it.err = err + } else if it.aborted { if glog.V(2) { glog.V(2).Infoln("Aborting subiterator") } diff --git a/graph/iterator/materialize_iterator_test.go b/graph/iterator/materialize_iterator_test.go new file mode 100644 index 0000000..aa749c5 --- /dev/null +++ b/graph/iterator/materialize_iterator_test.go @@ -0,0 +1,72 @@ +// Copyright 2014 The Cayley Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package iterator + +import ( + "errors" + "testing" + + //"github.com/google/cayley/graph" +) + +func TestMaterializeIteratorError(t *testing.T) { + retErr := errors.New("unique") + errIt := newTestIterator(false, retErr) + + // This tests that we properly return 0 results and the error when the + // underlying iterator returns an error. + mIt := NewMaterialize(errIt) + + if mIt.Next() != false { + t.Errorf("Materialize iterator did not pass through underlying 'false'") + } + if mIt.Err() != retErr { + t.Errorf("Materialize iterator did not pass through underlying Err") + } +} + +func TestMaterializeIteratorErrorAbort(t *testing.T) { + retErr := errors.New("unique") + errIt := newTestIterator(false, retErr) + + // This tests that we properly return 0 results and the error when the + // underlying iterator is larger than our 'abort at' value, and then + // returns an error. + or := NewOr() + or.AddSubIterator(NewInt64(1, int64(abortMaterializeAt+1))) + or.AddSubIterator(errIt) + + mIt := NewMaterialize(or) + + // Should get all the underlying values... + for i := 0; i < abortMaterializeAt+1; i++ { + if !mIt.Next() { + t.Errorf("Materialize iterator returned spurious 'false' on iteration %d", i) + return + } + if mIt.Err() != nil { + t.Errorf("Materialize iterator returned non-nil Err on iteration %d", i) + return + } + } + + // ... and then the error value + if mIt.Next() != false { + t.Errorf("Materialize iterator did not pass through underlying 'false'") + } + if mIt.Err() != retErr { + t.Errorf("Materialize iterator did not pass through underlying Err") + } +}