Exemple #1
0
// Create creates the given Node.
func (a *NodeAPI) Create(ctx context.Context, req *pb.CreateNodeRequest) (*pb.CreateNodeResponse, error) {
	var appEUI, devEUI lorawan.EUI64
	var appKey lorawan.AES128Key

	if err := appEUI.UnmarshalText([]byte(req.AppEUI)); err != nil {
		return nil, err
	}
	if err := devEUI.UnmarshalText([]byte(req.DevEUI)); err != nil {
		return nil, err
	}
	if err := appKey.UnmarshalText([]byte(req.AppKey)); err != nil {
		return nil, err
	}

	node := models.Node{
		DevEUI: devEUI,
		AppEUI: appEUI,
		AppKey: appKey,

		RXDelay:     uint8(req.RxDelay),
		RX1DROffset: uint8(req.Rx1DROffset),
	}
	if req.ChannelListID > 0 {
		node.ChannelListID = &req.ChannelListID
	}

	if err := storage.CreateNode(a.ctx.DB, node); err != nil {
		return nil, err
	}

	return &pb.CreateNodeResponse{}, nil
}
Exemple #2
0
func TestValidateDevNonce(t *testing.T) {
	Convey("Given a Node", t, func() {
		n := models.Node{
			UsedDevNonces: make([][2]byte, 0),
		}

		Convey("Then any given dev-nonce is valid", func() {
			dn := [2]byte{1, 2}
			So(n.ValidateDevNonce(dn), ShouldBeTrue)

			Convey("Then the dev-nonce is added to the used nonces", func() {
				So(n.UsedDevNonces, ShouldContain, dn)
			})
		})

		Convey("Given a Node has 10 used nonces", func() {
			n.UsedDevNonces = [][2]byte{
				{1, 1},
				{2, 2},
				{3, 3},
				{4, 4},
				{5, 5},
				{6, 6},
				{7, 7},
				{8, 8},
				{9, 9},
				{10, 10},
			}

			Convey("Then an already used nonce is invalid", func() {
				So(n.ValidateDevNonce([2]byte{1, 1}), ShouldBeFalse)

				Convey("Then the UsedDevNonces still has length 10", func() {
					So(n.UsedDevNonces, ShouldHaveLength, 10)
				})
			})

			Convey("Then a new nonce is valid", func() {
				So(n.ValidateDevNonce([2]byte{0, 0}), ShouldBeTrue)

				Convey("Then the UsedDevNonces still has length 10", func() {
					So(n.UsedDevNonces, ShouldHaveLength, 10)
				})

				Convey("Then the new nonce was added to the back of the list", func() {
					So(n.UsedDevNonces[9], ShouldEqual, [2]byte{0, 0})
				})
			})
		})
	})
}
Exemple #3
0
func TestNodeMethods(t *testing.T) {
	conf := common.GetTestConfig()

	Convey("Given a clean database with application", t, func() {
		db, err := OpenDatabase(conf.PostgresDSN)
		So(err, ShouldBeNil)
		common.MustResetDB(db)

		app := models.Application{
			AppEUI: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
			Name:   "test app",
		}
		So(CreateApplication(db, app), ShouldBeNil)

		Convey("When creating a node", func() {
			node := models.Node{
				DevEUI: [8]byte{8, 7, 6, 5, 4, 3, 2, 1},
				AppEUI: app.AppEUI,
				AppKey: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8},

				RXDelay:     2,
				RX1DROffset: 3,
			}
			So(CreateNode(db, node), ShouldBeNil)

			Convey("Whe can get it", func() {
				node2, err := GetNode(db, node.DevEUI)
				node2.UsedDevNonces = nil
				So(err, ShouldBeNil)
				So(node2, ShouldResemble, node)
			})

			Convey("Then get nodes returns a single item", func() {
				nodes, err := GetNodes(db, 10, 0)
				So(err, ShouldBeNil)
				So(nodes, ShouldHaveLength, 1)
				nodes[0].UsedDevNonces = nil
				So(nodes[0], ShouldResemble, node)
			})

			Convey("Then get nodes for AppEUI returns a single item", func() {
				nodes, err := GetNodesForAppEUI(db, app.AppEUI, 10, 0)
				So(err, ShouldBeNil)
				So(nodes, ShouldHaveLength, 1)
				nodes[0].UsedDevNonces = nil
				So(nodes[0], ShouldResemble, node)
			})

			Convey("Then get nodes count returns 1", func() {
				count, err := GetNodesCount(db)
				So(err, ShouldBeNil)
				So(count, ShouldEqual, 1)
			})

			Convey("Then get nodes count for AppEUI returns 1", func() {
				count, err := GetNodesForAppEUICount(db, app.AppEUI)
				So(err, ShouldBeNil)
				So(count, ShouldEqual, 1)
			})

			Convey("When updating the node", func() {
				node.AppKey = [16]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
				So(UpdateNode(db, node), ShouldBeNil)

				Convey("Then the nodes has been updated", func() {
					node2, err := GetNode(db, node.DevEUI)
					So(err, ShouldBeNil)
					node2.UsedDevNonces = nil
					So(node2, ShouldResemble, node)
				})
			})

			Convey("When deleting the node", func() {
				So(DeleteNode(db, node.DevEUI), ShouldBeNil)

				Convey("Then get nodes count returns 0", func() {
					count, err := GetNodesCount(db)
					So(err, ShouldBeNil)
					So(count, ShouldEqual, 0)
				})
			})
		})
	})
}
Exemple #4
0
func TestNodeAPI(t *testing.T) {
	conf := getConfig()

	Convey("Given a clean database and an API instance", t, func() {
		db, err := OpenDatabase(conf.PostgresDSN)
		So(err, ShouldBeNil)
		mustResetDB(db)

		ctx := Context{
			DB: db,
		}

		api := NewNodeAPI(ctx)

		Convey("Given an application is created (fk constraint)", func() {
			app := models.Application{
				AppEUI: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
				Name:   "test app",
			}
			// we need to create the app since the node has a fk constraint
			So(createApplication(ctx.DB, app), ShouldBeNil)

			node := models.Node{
				DevEUI:        [8]byte{8, 7, 6, 5, 4, 3, 2, 1},
				AppEUI:        [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
				AppKey:        [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
				UsedDevNonces: [][2]byte{},
			}

			Convey("When calling Create", func() {
				var devEUI lorawan.EUI64
				So(api.Create(node, &devEUI), ShouldBeNil)
				So(devEUI, ShouldEqual, node.DevEUI)

				Convey("Then the node has been created", func() {
					var node2 models.Node
					So(api.Get(node.DevEUI, &node2), ShouldBeNil)
					So(node2, ShouldResemble, node)

					Convey("Then the node can ben updated", func() {
						node.UsedDevNonces = [][2]byte{
							{1, 2},
						}
						So(api.Update(node, &devEUI), ShouldBeNil)
						So(api.Get(node.DevEUI, &node2), ShouldBeNil)
						So(node2, ShouldResemble, node)
					})

					Convey("Then the node can be deleted", func() {
						So(api.Delete(node.DevEUI, &devEUI), ShouldBeNil)
						So(api.Get(node.DevEUI, &node2), ShouldNotBeNil)
					})
				})

				Convey("Then the list of nodes has size 1", func() {
					var nodes []models.Node
					So(api.GetList(models.GetListRequest{
						Limit:  10,
						Offset: 0,
					}, &nodes), ShouldBeNil)
					So(nodes, ShouldHaveLength, 1)
				})
			})
		})
	})
}
Exemple #5
0
func TestGetCFListForNode(t *testing.T) {
	conf := getConfig()

	Convey("Given an application, node (without channel-list) and channel-list with 2 channels", t, func() {
		db, err := OpenDatabase(conf.PostgresDSN)
		So(err, ShouldBeNil)
		mustResetDB(db)

		ctx := Context{
			DB: db,
		}

		channelList := models.ChannelList{
			Name: "test channels",
		}
		So(createChannelList(ctx.DB, &channelList), ShouldBeNil)
		So(createChannel(ctx.DB, &models.Channel{
			ChannelListID: channelList.ID,
			Channel:       3,
			Frequency:     868400000,
		}), ShouldBeNil)
		So(createChannel(ctx.DB, &models.Channel{
			ChannelListID: channelList.ID,
			Channel:       4,
			Frequency:     868500000,
		}), ShouldBeNil)

		app := models.Application{
			AppEUI: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
			Name:   "test app",
		}
		So(createApplication(ctx.DB, app), ShouldBeNil)

		node := models.Node{
			DevEUI: [8]byte{8, 7, 6, 5, 4, 3, 2, 1},
			AppEUI: app.AppEUI,
		}
		So(createNode(ctx.DB, node), ShouldBeNil)

		Convey("Then getCFListForNode returns nil", func() {
			cFList, err := getCFListForNode(ctx.DB, node)
			So(err, ShouldBeNil)
			So(cFList, ShouldBeNil)
		})

		Convey("Given the node has the channel-list configured", func() {
			node.ChannelListID = &channelList.ID
			So(updateNode(ctx.DB, node), ShouldBeNil)

			Convey("Then getCFListForNode returns the CFList with the configured channels", func() {
				cFList, err := getCFListForNode(ctx.DB, node)
				So(err, ShouldBeNil)

				So(cFList, ShouldResemble, &lorawan.CFList{
					868400000,
					868500000,
					0,
					0,
					0,
				})
			})

			Convey("Given the configured ISM band does not allow a CFList", func() {
				defer func() {
					Band.ImplementsCFlist = true
				}()
				Band.ImplementsCFlist = false

				Convey("Then getCFListForNode returns nil", func() {
					cFList, err := getCFListForNode(ctx.DB, node)
					So(err, ShouldBeNil)
					So(cFList, ShouldBeNil)
				})
			})
		})

	})
}